Sortuj poszczególne elementy listy w kolejności malejącej według częstotliwości

12

Napisz funkcję, która pobiera listę lub tablicę i zwraca listę różnych elementów, posortowanych w porządku malejącym według częstotliwości.

Przykład:

Dany:

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

Oczekiwana wartość zwrotu:

["Doe","Harry","John","Dick"]
belvi
źródło
Kod-golf czy wyzwanie kodem?
marinus
Kod-golf. To był błąd. Po prostu popraw to
belvi

Odpowiedzi:

13

APL (14)

{∪⍵[⍒+⌿∘.≡⍨⍵]}

Jest to funkcja, która pobiera listę, np .:

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

Wyjaśnienie:

  • ∘.≡⍨⍵: porównaj każdy element w tablicy z innymi elementami w tablicy, dając macierz
  • +⌿: zsumuj kolumny macierzy, podając ile razy występuje każdy element
  • : podaj wskaźniki w dół
  • ⍵[... ]: zmiana kolejności według podanych wskaźników
  • : zdobądź unikalne elementy
marinus
źródło
3
A jednak jakoś nazywają przejście od tego zwięzłego dowcipnego języka do Java „postęp”? (-:
hippietrail
8

Python 3-47 43; Python 2 - 40 39

W przypadku Python 3:

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

W przypadku Python 2:

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

Próbny:

>>> names = ["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"]
>>> f(names)
['Doe', 'Harry', 'John', 'Dick']
Blckknght
źródło
1
Próbowałem opublikować to samo, ale tutaj jest modyfikacja. f=lambda n:sorted(set(n),cmp,n.count,1)39 znaków
TY
1
Hmm, nie zdawałem sobie sprawy, że można przekazać zarówno funkcję inną niż Brak, jak cmpi keyfunkcję. Chłodny.
Blckknght
1
Nieco krótszy:f=lambda n:sorted(set(n),key=n.count)[::-1]
grc
Dzięki @grc, obca buźka zapisuje niektóre znaki w przypadku Python 3.
Blckknght
5

Mathematica, 31

Sort[GatherBy@n][[-1;;1;;-1,1]]

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

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

Ajasja
źródło
Cholera, doprowadziłeś mnie tam: D
Yves Klett
@YvesKlett Thanks. Myślę o pozbyciu się Reverse, ale Sort[GatherBy@n][[-1;;1, 1]]nie działa :). Jakieś pomysły?
Ajasja
4

Mathematica (26 37)

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

Last/@Gather@n~SortBy~Length//Reverse

{„Doe”, „Harry”, „John”, „Dick”}


Mathematica V10 + (26) :

Keys@Sort[Counts[n],#>#2&]
Yves Klett
źródło
@garej starsza wersja w użyciu. Opublikować jako inną odpowiedź?
Yves Klett
Dodałem do ciebie, jeśli nie masz nic przeciwko ...
garej
@garej. Dzięki, doskonałe rozwiązanie!
Yves Klett
3

Perl 6 (36 bajtów, 35 znaków)

»można zastąpić >>, jeśli nie możesz obsługiwać UTF-8. Jestem prawie pewien, że może to być krótsze, ale Bagklasa zachowuje się dość dziwnie (niestety) i nie jest tak naprawdę ukończona, ponieważ jest stosunkowo nowa (ale może liczyć argumenty). {}deklaruje anonimową funkcję.

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

Przykładowe dane wyjściowe (z 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
Konrad Borowski
źródło
3

Rubin: 34 37 postacie

f=->a{a.sort_by{|z|-a.count(z)}&a}

(edytowane: poprzednie 30-znakowe rozwiązanie było ciałem funkcji)

przepisane
źródło
Możesz przyciąć kilka znaków za pomocą f=->a{a.sort_by{|z|-a.count(z)}&a}. &Robi Uniq.
histokrata
3

GolfScript, 14 znaków (19 jako nazwana funkcja, również 14 jako pełny program)

:a.|{[.]a\-,}$

Ten kod pobiera tablicę na stos i sortuje unikalne elementy w porządku malejącym według liczby wystąpień. Na przykład, jeśli tablica wejściowa to:

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

wtedy tablica wyjściowa będzie

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

Uwaga: powyższy kod jest czystą sekwencją instrukcji. Aby przekształcić go w funkcję o nazwie, zawiń ją w nawiasy klamrowe i przypisz do nazwy, jak w:

{:a.|{[.]a\-,}$}:f;

Alternatywnie, aby przekształcić kod w pełny program, który odczytuje listę ze standardowego wejścia (używając notacji listy pokazanej powyżej) i drukuje ją na standardowe wyjście, ~dołącza i dołącza `do kodu. W [. tym przypadku można pominąć (ponieważ wiemy, że na stosie nie będzie nic więcej), więc wynikowy program składający się z 14 znaków będzie:

~:a.|{]a\-,}$`

Jak to działa?

  • :azapisuje kopię oryginalnej tablicy w zmiennej ado późniejszego wykorzystania.

  • .| oblicza zestaw unii tablicy z samym sobą, eliminując duplikaty jako efekt uboczny.

  • { }$sortuje zduplikowaną tablicę za pomocą niestandardowych kluczy sortowania obliczonych przez kod w nawiasach klamrowych. Ten kod pobiera każdy element tablicy, używa odejmowania tablicy, aby usunąć go z oryginalnej zapisanej tablicy wejściowej a, i zlicza liczbę pozostałych elementów. W ten sposób elementy są sortowane w malejącej kolejności częstotliwości.

Ps. Zobacz tutaj oryginalną 30-znakową wersję.

Ilmari Karonen
źródło
Myślę, że to [a\])^powinno być równoważne [.;]a\-. Sortowanie według liczby niepasujących elementów to dobry pomysł.
Peter Taylor
Niestety, nie: ^zwija duplikaty, -nie robi. (I ITYM (, nie ).) Działałoby , [a\](\-ale nie zapisywało żadnych znaków.
Ilmari Karonen
2

R: 23 znaki

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

names(sort(table(n),T))
## [1] "Doe"   "Harry" "John"  "Dick" 

Ale to nie używa tak piękny skrót Tdo TRUE...

Henrik
źródło
1

jeśli to może pasować tutaj: 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

LUB

with cte as
(

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

select name from cte order by x desc

zobacz to w akcji

Vhadalgi
źródło
1
Dlaczego CTE? select name from #t1 group by name order by count(*) desc
manatwork
1

PHP, 63 62 61 znaków

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

Próbny:

$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 )
Vereos
źródło
spójrz na array_count_values()… To wszystko, czego musisz użyć (w tym arsort())
bwoebi
array_count_values()jak widzę, nie usuwa zduplikowanych wartości ani nie porządkuje ich.
Vereos
Usuwa duplikaty… Po prostu ich nie porządkuje… => arsort
bwoebi
@bwoebi Masz rację. Niestety napisanie tego w ten sposób jest o 1 znak dłuższe niż ta odpowiedź.
Tim Seguine
Dlaczego droga jest array_count_valuesdłuższa? <?$u=array_count_values($_GET);arsort($u);print_r($u);moim zdaniem jest 54 bajtów
Jörg Hülsermann
1

Ruby: 59 znaków

f=->n{n.group_by{|i|i}.sort_by{|i|-i[1].size}.map{|i|i[0]}}

Przykładowy przebieg:

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"]
człowiek w pracy
źródło
1

Mathematica, 39 znaków

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

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

f@names

{Doe, Harry, John, Dick}

Chris Degnen
źródło
1

JavaScript (ECMAScript5): 118 113 znaków

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]})}

http://jsfiddle.net/mblase75/crg5B/

Blazemonger
źródło
Harmonii w funkcji tłuszcz strzałek : f=n=>{m={};n.forEach(e=>m[e]=m[e]+1||1);return Object.keys(m).sort((a,b)=>m[b]-m[a])}. (Obecnie tylko w Firefox.)
manatwork
Możesz użyć m[n[i]]=-~m[n[i]]do zwiększania i nie potrzebujesz {} wokół całego obwodu pętli.
Neil,
1

Haskell - 53 znaków

import Data.List
import Data.Ord

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

Objaśnienie: pierwsze dwa wiersze to konieczne importowanie, następny wiersz kodu to podpis typu (generalnie nie jest to konieczne), faktyczna funkcja to ostatni wiersz. Funkcja sortuje listę według naturalnego porządku, grupuje równe elementy w listy, sortuje listę według malejącego rozmiaru i pobiera pierwszy element z każdej listy.

całkowita długość wraz z importem: 120

bez importu, ale z podpisem typu: 86

sama funkcja: 53

jgon
źródło
1

Clojure: 43 znaków

Funkcjonować:

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

Demo (w repl):

user=> (def names ["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"])
#'user/names
user=> (#(keys(sort-by(comp - val)(frequencies %))) names)
("Doe" "Harry" "John" "Dick")
Charles Simpson
źródło
0

Perl

Aby spełnić specyfikację wejścia / wyjścia potrzebuję 120 znaków

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

czysty najkrótszy kod, biorąc jeden element w wierszu i drukując jeden element w wierszu Potrzebuję tylko 55 znaków

$a{$_}++ while(<>);print sort{$a{$a}<=>$a{$b}}keys %a)
Hildred
źródło
0

C #: 111 znaków

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

(wewnątrz klasy)

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

Łania

Złupić

Jan

Kutas

Proste rozwiązanie wykorzystujące LINQ.

paavohtl
źródło
Można również usunąć .ToList () , ponieważ sekwencja jest wyliczana za pomocą foreach
Adam Speight
To prawda, ale musiałbym zmienić typ zwracany na IEnumerable <ciąg> .
paavohtl
0

R (22)

names(sort(-table(x)))

Jako funkcja zajęłaby 11 dodatkowych znaków.

Stosowanie:

> x = c("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John")
> names(sort(-table(x)))
[1] "Doe"   "Harry" "John"  "Dick"
lambruscoAcido
źródło
To pobiera dane wejściowe ze zmiennej, która jest niedozwolona przez konsensus społeczności .
Esolanging Fruit
0

Scala (71)

(x.groupBy(a=>a)map(t=>(t._1,t._2.length))toList)sortBy(-_._2)map(_._1)

Nie golfowany:

def f(x:Array[String]) =
  (x.groupBy(a => a) map (t => (t._1, t._2.length)) toList) 
    sortBy(-_._2) map(_._1)
lambruscoAcido
źródło
0

J, 8 bajtów

~.\:#/.~

Stosowanie

Nazwy są przechowywane jako tablica ciągów w ramkach.

   'John';'Doe';'Dick';'Harry';'Harry';'Doe';'Doe';'Harry';'Doe';'John'
┌────┬───┬────┬─────┬─────┬───┬───┬─────┬───┬────┐
│John│Doe│Dick│Harry│Harry│Doe│Doe│Harry│Doe│John│
└────┴───┴────┴─────┴─────┴───┴───┴─────┴───┴────┘
   f =: ~.\:#/.~
   f 'John';'Doe';'Dick';'Harry';'Harry';'Doe';'Doe';'Harry';'Doe';'John'
┌───┬─────┬────┬────┐
│Doe│Harry│John│Dick│
└───┴─────┴────┴────┘

Wyjaśnienie

~.\:#/.~   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
mile
źródło
0

CJam, 15 bajtów (być może niekonkurujących)

q~$e`{0=W*}$1f=

Może to korzystać z funkcji CJam po opublikowaniu tego wyzwania. Jestem zbyt leniwy, by to sprawdzić.

Esolanging Fruit
źródło