Write a function which takes a list or array, and returns a list of the distinct elements, sorted in descending order by frequency.




Expected return value:

  • \$\begingroup\$ Code-golf or code-challenge? \$\endgroup\$ – marinus Jan 3 '14 at 11:15
  • \$\begingroup\$ Code-golf. That was mistake. Just correct it \$\endgroup\$ – belvi Jan 3 '14 at 11:16

21 Answers 21


APL (14)


This is a function that takes a list, e.g.:

 John  Doe  Dick  Harry  Harry  Doe  Doe  Harry  Doe  John 
      {∪⍵[⍒+⌿∘.≡⍨⍵]} names
 Doe  Harry  John  Dick


  • ∘.≡⍨⍵: compare each element in the array to each other element in the array, giving a matrix
  • +⌿: sum the columns of the matrix, giving how many times each element occurs
  • : give indices of downward sort
  • ⍵[...]: reorder by the given indices
  • : get the unique elements
| improve this answer | |
  • 3
    \$\begingroup\$ And yet somehow they call going from this concise witty language to Java "progress"? (-: \$\endgroup\$ – hippietrail Jan 3 '14 at 17:23

Python 3 - 47 43; Python 2 - 40 39

For Python 3:

f=lambda n:sorted(set(n),key=n.count)[::-1]

For Python 2:

f=lambda n:sorted(set(n),cmp,n.count,1)


>>> names = ["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"]
>>> f(names)
['Doe', 'Harry', 'John', 'Dick']
| improve this answer | |
  • 1
    \$\begingroup\$ I was trying to post the same, but here is a modification. f=lambda n:sorted(set(n),cmp,n.count,1) 39 characters \$\endgroup\$ – YOU Jan 3 '14 at 11:33
  • 1
    \$\begingroup\$ Hmm, I didn't realize you could pass both a non-None cmp function and a key function. Cool. \$\endgroup\$ – Blckknght Jan 3 '14 at 11:35
  • 1
    \$\begingroup\$ A bit shorter: f=lambda n:sorted(set(n),key=n.count)[::-1] \$\endgroup\$ – grc Jan 3 '14 at 13:07
  • \$\begingroup\$ Thanks @grc, the alien smiley does save some characters in the Python 3 case. \$\endgroup\$ – Blckknght Jan 3 '14 at 21:48

Mathematica, 31


{"Doe", "Harry", "John", "Dick"}

(With n = {"John", "Doe", "Dick", "Harry", "Harry", "Doe", "Doe", "Harry", "Doe", "John"})

| improve this answer | |
  • \$\begingroup\$ Darn, you got me there :D \$\endgroup\$ – Yves Klett Jan 3 '14 at 15:39
  • \$\begingroup\$ @YvesKlett Thanks. I'm thinking of getting rid of Reverse, but Sort[GatherBy@n][[-1;;1, 1]] does not work:). Any ideas? \$\endgroup\$ – Ajasja Jan 3 '14 at 15:41
  • \$\begingroup\$ Ahh, got it mathematica.stackexchange.com/a/22320/745 \$\endgroup\$ – Ajasja Jan 3 '14 at 15:45

Mathematica (26 37)

With n = {"John", "Doe", "Dick", "Harry", "Harry", "Doe", "Doe", "Harry", "Doe", "John"}:


{"Doe", "Harry", "John", "Dick"}

Mathematica V10+ (26):

| improve this answer | |
  • \$\begingroup\$ @garej older version in use. Post as another answer? \$\endgroup\$ – Yves Klett Jun 1 '17 at 20:18
  • \$\begingroup\$ I've added to yours if you do not mind... \$\endgroup\$ – garej Jun 1 '17 at 20:23
  • \$\begingroup\$ @garej. Thanks, excellent solution! \$\endgroup\$ – Yves Klett Jun 1 '17 at 20:32

Perl 6 (36 bytes, 35 characters)

» can be replaced with >>, if you cannot handle UTF-8. I'm almost sure this could be shorter, but the Bag class is relatively strange in its behavior (sadly), and isn't really complete, as it's relatively new (but it can count arguments). {} declares an anonymous function.

{(sort -*.value,pairs bag @_)».key}

Sample output (from Perl 6 REPL):

> my @names = ("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John")
John Doe Dick Harry Harry Doe Doe Harry Doe John
> {(sort -*.value,pairs bag @_)».key}(@names)
Doe Harry John Dick
| improve this answer | |

Ruby: 34 37 characters


(edited: previous 30-char solution was the body of the function)

| improve this answer | |
  • \$\begingroup\$ You can trim a few characters with f=->a{a.sort_by{|z|-a.count(z)}&a} . The & does a uniq. \$\endgroup\$ – histocrat Jan 3 '14 at 23:02

GolfScript, 14 chars (19 as named function, also 14 as full program)


This code takes an array on the stack and sorts its unique elements in descending order by number of occurrences. For example, if the input array is:

["John" "Doe" "Dick" "Harry" "Harry" "Doe" "Doe" "Harry" "Doe" "John"]

then the output array will be

["Doe" "Harry" "John" "Dick"]

Note: The code above is a bare sequence of statements. To turn it into a named function, wrap it in braces and assign it to a name, as in:


Alternatively, to turn the code into a full program that reads a list from standard input (using the list notation shown above) and prints it to standard output, prepend ~ and append ` to the code. The [. can be omitted in this case (since we know there will be nothing else on the stack), so that the resulting 14-character program will be:


How does it work?

  • :a saves a copy of the original array in the variable a for later use.

  • .| computes the set union of the array with itself, eliminating duplicates as a side effect.

  • { }$ sorts the de-duplicated array using the custom sort keys computed by the code inside the braces. This code takes each array element, uses array subtraction to remove it from the original input array saved in a, and counts the number of remaining elements. Thus, the elements get sorted in decreasing order of frequency.

Ps. See here for the original 30-character version.

| improve this answer | |
  • \$\begingroup\$ I think that [a\])^ should be equivalent to [.;]a\-. Sorting by number of non-matching elements is a nice idea. \$\endgroup\$ – Peter Taylor Jan 4 '14 at 21:07
  • \$\begingroup\$ Alas, no: ^ collapses duplicates, - doesn't. (And ITYM (, not ).) [a\](\- would work, but wouldn't save any characters. \$\endgroup\$ – Ilmari Karonen Jan 4 '14 at 21:21

R: 23 characters

n <- c("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John")

## [1] "Doe"   "Harry" "John"  "Dick" 

But it uses the not so nice shortcut of T to TRUE...

| improve this answer | |

if this could fit here : In sql-server

create table #t1 (name varchar(10))
insert into #t1 values ('John'),('Doe'),('Dick'),('Harry'),('Harry'),('Doe'),('Doe'),('Harry'),('Doe'),('John')

select name from #t1 group by name order by count(*) desc


with cte as

select name,count(name) as x from #t1 group by name

select name from cte order by x desc

see it in action

| improve this answer | |
  • 1
    \$\begingroup\$ Why the CTE? select name from #t1 group by name order by count(*) desc \$\endgroup\$ – manatwork Jan 3 '14 at 11:44

PHP, 63 62 61 chars

function R($a){foreach($a as$v)$b[$v]++;arsort($b);return$b;}


$c = array("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John");
$d = print_r(R($c));

Array ( [Doe] => 4 [Harry] => 3 [John] => 2 [Dick] => 1 )
| improve this answer | |
  • \$\begingroup\$ have a look at array_count_values()… That's all you have to use (including arsort()) \$\endgroup\$ – bwoebi Jan 3 '14 at 11:50
  • \$\begingroup\$ array_count_values() does not delete duplicated values, nor orders them, as I can see. \$\endgroup\$ – Vereos Jan 3 '14 at 12:01
  • \$\begingroup\$ It deletes the duplicates … It just doesn't order them… => arsort \$\endgroup\$ – bwoebi Jan 3 '14 at 12:26
  • \$\begingroup\$ @bwoebi You are right. Unfortunately writing it that way is 1 character longer than this answer. \$\endgroup\$ – Tim Seguine Jan 3 '14 at 12:55
  • \$\begingroup\$ Why is the way with array_count_values longer? <?$u=array_count_values($_GET);arsort($u);print_r($u); are 54 Bytes in my opinion \$\endgroup\$ – Jörg Hülsermann Jun 2 '17 at 9:37

Ruby: 59 characters


Sample run:

irb(main):001:0> f=->n{n.group_by{|i|i}.sort_by{|i|-i[1].size}.map{|i|i[0]}}
=> #<Proc:0x93b2e10@(irb):2 (lambda)>

irb(main):004:0> f[["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"]]
=> ["Doe", "Harry", "John", "Dick"]
| improve this answer | |

Mathematica, 39 characters

f = Reverse[First /@ SortBy[Tally@#, Last]] &

names = {"John", "Doe", "Dick", "Harry", "Harry",
         "Doe", "Doe", "Harry", "Doe", "John"};


{Doe, Harry, John, Dick}

| improve this answer | |

JavaScript (ECMAScript5): 118 113 characters

function f(n){m={}
for(i in n){m[n[i]]=m[n[i]]+1||1}
return Object.keys(m).sort(function(a,b){return m[b]-m[a]})}


| improve this answer | |
  • \$\begingroup\$ With Harmony's fat arrow functions: f=n=>{m={};n.forEach(e=>m[e]=m[e]+1||1);return Object.keys(m).sort((a,b)=>m[b]-m[a])}. (Currently only in Firefox.) \$\endgroup\$ – manatwork Jan 3 '14 at 18:55
  • \$\begingroup\$ You can use m[n[i]]=-~m[n[i]] to increment, and you don't need {}s around the loop body. \$\endgroup\$ – Neil May 9 '16 at 21:36

Haskell - 53 Characters

import Data.List
import Data.Ord

f :: (Eq a, Ord a) => [a] -> [a]
f=map head.(sortBy$flip$comparing length).group.sort

Explanation: the first two lines are necessary imports, the next line of code is the type signature (generally not necessary), the actual function is the last line. The function sorts the list by its natural ordering, groups equal elements into lists, sorts the list of lists by descending size, and takes the first element in each list.

total length including imports: 120

w/o imports but with type signature: 86

function itself: 53

| improve this answer | |

Clojure: 43 characters


#(keys(sort-by(comp - val)(frequencies %)))

Demo (in repl):

user=> (def names ["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"])
user=> (#(keys(sort-by(comp - val)(frequencies %))) names)
("Doe" "Harry" "John" "Dick")
| improve this answer | |


to meet given i/o spec I need 120 chars

s!"([^"]+)"[],]!$a{$1}++!e while(<>);print 'MostOccuring = [',join(',',map{qq("$_")}sort{$a{$a}<=>$a{$b}}keys %a),"]\n"

pure shortest code by taking one item per line and printing one item per line I only need 55 chars

$a{$_}++ while(<>);print sort{$a{$a}<=>$a{$b}}keys %a)
| improve this answer | |

C#: 111 characters

List<string>M(List<string>l){return l.GroupBy(q=>q).OrderByDescending(g=>g.Count()).Select(g=>g.Key).ToList();}

(inside a class)

var names = new List<string> {"John", "Doe", "Dick", "Harry", "Harry", "Doe", "Doe", "Harry", "Doe", "John"};
foreach(var s in M(names))





A simple solution using LINQ.

| improve this answer | |
  • \$\begingroup\$ You could also remove the .ToList(), since the sequence get enumerated via the foreach \$\endgroup\$ – Adam Speight Jan 3 '14 at 22:23
  • \$\begingroup\$ That's true, but then I'd have to change the return type into IEnumerable<string>. \$\endgroup\$ – paavohtl Jan 4 '14 at 0:06

R (22)


As a function it would take 11 more characters.


> x = c("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John")
> names(sort(-table(x)))
[1] "Doe"   "Harry" "John"  "Dick"
| improve this answer | |

Scala (71)



def f(x:Array[String]) =
  (x.groupBy(a => a) map (t => (t._1, t._2.length)) toList) 
    sortBy(-_._2) map(_._1)
| improve this answer | |

J, 8 bytes



The names are stored as an array of boxed strings.

   f =: ~.\:#/.~
   f 'John';'Doe';'Dick';'Harry';'Harry';'Doe';'Doe';'Harry';'Doe';'John'


~.\:#/.~   Input: A
    #/.~   Finds the size of each set of identical items (Frequencies)
~.         List the distinct values in A
           Note: the distinct values and frequencies will be in the same order
  \:       Sort the distinct values in decreasing order according to the frequencies
           Return the sorted list implicitly
| improve this answer | |

CJam, 15 bytes (possibly non-competing)


This may use CJam features from after this challenge was posted. I'm too lazy to check.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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