How to sort and extract a list containing products
sector2 = {k, r};
list = Inactivate[{a b a, a k b, a k r}, Times]
Count[Alternatives @@ sector2] /@ list
{0, 1, 2}
Sorting
SortBy[Count[Alternatives @@ sector2]] @ list
Reverse[list]
SortBy[Count[Alternatives @@ sector2]] @ %
Selecting sublists
lstW0S2Elements = Select[Count[Alternatives @@ sector2]@# == 0 &]@list (* or *)
lstW0S2Elements = Pick[list, Count[Alternatives @@ sector2] /@ list, 0]
lstW1S2Elements = Select[Count[Alternatives @@ sector2]@# == 1 &]@list (* or *)
lstW1S2Elements = Pick[list, Count[Alternatives @@ sector2] /@ list, 1]
lstW2S2Elements = Select[Count[Alternatives @@ sector2]@# == 2 &]@list (* or *)
lstW2S2Elements = Pick[list, Count[Alternatives @@ sector2] /@ list, 2]
And using variant of J.M.'s answer with an alternative specification of keys in GroupBy
:
gb = GroupBy[list, Count[Alternatives @@ sector2]]
lstW0S2Elements = gb @ 0
Update: If you wish to work with an input list with multiplication already carried out:
lst0 = {a^2 b, a b k, a k r};
GroupBy[lst0,
Count[# /. { Power -> Table, Times -> Flatten@*List}, Alternatives @@ sector2] &]
<|0 -> {a^2 b}, 1 -> {a b k}, 2 -> {a k r}|>
sector1 = {a, b};
GroupBy[lst0,
Count[# /. { Power -> Table, Times -> Flatten@*List}, Alternatives @@ sector1] &]
<|3 -> {a^2 b}, 2 -> {a b k}, 1 -> {a k r}|>
First, you must write products with a space, otherwise it is considered a name. Note that A A
will be written as A square.
I assume that elements of different sectors or not already ordered alphabetically as in your example (Sector1: A,B, Sector 2: K,R). In this case sorting would be trivial.
To sort lists according to elements of sector 2 we first extract these elements. Then we use Order
to determine if the products are in order or not.
Now you can sort ascending or descending. For the first case you would have:
list = {A K R, A K B, A B A};
Sort[list, Order[Cases[#1, K | R], Cases[#2, K | R]] &]
(*{A^2 B, A B K, A K R}*)
For descending sort you would have to change the sign of Order
:
list = {A B A, A K R, A K B};
Sort[list, -Order[Cases[#1, K | R], Cases[#2, K | R]] &]
(*{A K R, A B K, A^2 B}*)
Things are a little easier if you use NonCommutativeMultiply[]
instead to represent your products (unless you know your products are commutative). Then, it is just a matter of using GroupBy[]
with an appropriate criterion:
sector2 = {k, r};
prods = {a ** b ** a, a ** k ** b, a ** k ** r};
GroupBy[prods, Count[#, x_ /; MemberQ[sector2, x]] &] // KeySort
<|0 -> {a ** b ** a}, 1 -> {a ** k ** b}, 2 -> {a ** k ** r}|>
SortBy[]
is also usable:
SortBy[prods, Count[#, x_ /; MemberQ[sector2, x]] &]
{a ** b ** a, a ** k ** b, a ** k ** r}