Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I want to select all elements that repeat 4 times in the list. I propose this code

list = {a, a, a, b, c, a, b, b, b, e};

elementsplus4 = Select[list, Count[list, #] == 4 &];

I obtain:

{a, a, a, b, a, b, b, b}

How can I obtain just {a,b}

share|improve this question
2  
DeleteDuplicates –  Ajasja Jan 13 at 7:08
6  
Cases[Tally[list], {i_, 4}:>i] –  Rojo Jan 13 at 7:09
add comment

4 Answers

up vote 15 down vote accepted

You may use Tally to finish the task as follows:

Cases[Tally[list], {x_, 4} :> x]

the result will be {a,b}.

share|improve this answer
    
Yup, that's the one. +1 –  Mr.Wizard Jan 13 at 7:18
    
Cases[Tally[list], {x_, 4} -> x] seems to work too. –  DumpsterDoofus Jan 28 at 16:06
add comment

The code given by Rojo and sunt05 is almost surely the cleanest:

Cases[Tally @ list, {x_, 4} :> x]

However, here are some other possibilities:

Cases[Split @ Sort @ list, {x_, _, _, _} :> x]

Cases[Split @ Sort @ list, {Repeated[x_, {4}]} :> x]

Cases[Last @ Reap[Sow[1, list], _, {#, Tr@#2} &], {x_, 4} :> x]

Module[{c},
  c[_] = 0;
  Scan[c[#]++ &, list];
  Cases[DownValues[c], (_@_@x_ :> 4) :> x]
]

Performance

Interestingly, some of these may be significantly faster than Tally in certain cases:

list = FromCharacterCode /@ RandomInteger[15000, 100000];

Cases[Tally @ list, {x_, 4} :> x]                               // Timing // First

Cases[Last @ Reap[Sow[1, list], _, {#, Tr@#2} &], {x_, 4} :> x] // Timing // First

Module[{c},
 c[_] = 0;
 Scan[c[#]++ &, list];
 Cases[DownValues[c], (_@_@x_ :> 4) :> x]
] // Timing // First
0.546

0.109

0.2622

Since it seems to be only in the case of String objects that Sow/Reap is faster, for clarity one might write the second method as:

stringTally = Last @ Reap[Sow[1, #], _, {#, Tr@#2} &] &;

Cases[stringTally @ list, {x_, 4} :> x] // Timing // First
0.103

Addendum

The OP wrote: "I want to list all elements that appear at least four times." In light of that here are all the methods modified accordingly:

stringTally = Last @ Reap[Sow[1, #], _, {#, Tr@#2} &] &;

Cases[stringTally @ list, {x_, n_} /; n >= 4 :> x]

Cases[Split @ Sort @ list, {x_, _, _, __} :> x]

Cases[Split @ Sort @ list, {Repeated[x_, {4, ∞}]} :> x]

Cases[Last @ Reap[Sow[1, list], _, {#, Tr@#2} &], {x_, n_} /; n >= 4 :> x]

Module[{c},
  c[_] = 0;
  Scan[c[#]++ &, list];
  Cases[DownValues[c], (_@_@x_ :> n_) /; n >= 4 :> x]
]
share|improve this answer
    
How can we change Cases[Last @ Reap[Sow[1, list], _, {#, Tr@#2} &], {x_, 4} :> x] when we need to select the elements repated greater than 4 times ? –  developer2000 Jan 13 at 7:50
    
@developer2000 just change the 4 in {x_, 4} :> x, as you would with the Tally solution. –  Mr.Wizard Jan 13 at 7:52
    
I think that you did not understand me. I would select the elements that repeated 4 times, 5 times, 6 times and so on (greater than 4). I think that I can use Table[Cases[stringTally @ list, {x_, i} :> x],{i,4,n}] but is there any other pretty solution? –  developer2000 Jan 13 at 9:02
    
@developer2000 Oh, that was not clear. Do you mean that you wish to list the elements that appear four times separately from those that appear five times, etc., or list all elements that appear at least four times? –  Mr.Wizard Jan 13 at 9:10
    
I want to list all elements that appear at least four times. sorry for the bed english. –  developer2000 Jan 13 at 11:37
show 1 more comment
DeleteDuplicates[Select[list, Count[list, #] == 4 &]]
share|improve this answer
add comment

Or be lazy and just run the set theory-inspired Union[] command over the result of your initial computation, provided that the initial one yields the results you listed -- it doesn't for me.

share|improve this answer
    
sometimes being lazy is a good choice!! I know this solution! –  developer2000 Jan 13 at 18:20
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.