a special Tally function in mathematica
I am wondering how one can write a special Tally function, which treats the following list {{{1,0},{2,1,3}},{{1,1},{0,1,1}},{{2,1,2},{3,2}},{{1,0},{2,1}}}
as if:
- as long as dimensions match, it is equivalent. For example,
{{1,0},{2,1,3}}
and{{1,1},{0,1,1}}
are equivalent, but not with{{1,0},{2,1}}
. - ordering also does not matter. For ex开发者_JAVA技巧ample,
{{1,0},{2,1,3}}
and{{2,1,2},{3,2}}
are equivalent.
The elements of the level 1
list can be artitarily nested. How can I write such a function?
Many thanks.
(1) Replace all integers with 0. (2) Sort at level one. This gives a unique representative for every class in the list.
ll2 = Map[Sort, ll /. aa_Integer -> 0]
Out[9]= {{{0, 0}, {0, 0, 0}}, {{0, 0}, {0, 0, 0}}, {{0, 0}, {0, 0, 0}}, {{0, 0}, {0, 0}}}
Tally[ll2]
Out[10]= {{{{0, 0}, {0, 0, 0}}, 3}, {{{0, 0}, {0, 0}}, 1}}
Daniel Lichtblau Wolfram Research
Very similar to @Daniel's answer, but preserves a member of each class:
In[9]:= Tally[list, (Sort[Length /@ #] == Sort[Length /@ #2]) &]
Out[9]= {{{{1, 0}, {2, 1, 3}}, 3}, {{{1, 0}, {2, 1}}, 1}}
Using SelectEquivalents
SelectEquivalents[list, Dimensions, #&, {#2[[1]], Length@#2}&]
which gives the same thing as Michael's answer, or
SelectEquivalents[list, Dimensions, #&, {#2[[1]] /. _Integer -> 0, Length@#2}&]
which gives Daniel's answer. Or, my personal favorite
SelectEquivalents[list, Dimensions, #&, {#1, Length@#2}&]
which gives
{{{2},3}, {{2,2}, 1}}
But, that reveals a flaw in using Dimension
, in that it does not know what to report when the sublists are of different dims, so if we replace Dimension
with Sort@Map[Length,#,{1,Infinity}]&
, we can begin to handle arbitrary dimensions. This gives
{{{2, 3}, 3}, {{2, 2}, 1}}
So, the dimensionality of each sublist is revealed. This does not sort below the first dimension, and I do not see how it can be immediately fixed.
精彩评论