Sortieren Sie die einzelnen Elemente einer Liste in absteigender Reihenfolge nach Häufigkeit

12

Schreiben Sie eine Funktion, die eine Liste oder ein Array aufnimmt und eine Liste der verschiedenen Elemente zurückgibt, sortiert in absteigender Reihenfolge nach Häufigkeit.

Beispiel:

Gegeben:

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

Erwarteter Rückgabewert:

["Doe","Harry","John","Dick"]
belvi
quelle
Code-Golf oder Code-Challenge?
Marinus
Code-Golf. Das war ein Fehler. Korrigieren Sie es
einfach

Antworten:

13

APL (14)

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

Dies ist eine Funktion, die eine Liste annimmt, zB:

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

Erläuterung:

  • ∘.≡⍨⍵: Vergleiche jedes Element im Array mit jedem anderen Element im Array, um eine Matrix zu erhalten
  • +⌿: summiere die Spalten der Matrix und gebe an, wie oft jedes Element vorkommt
  • : Indexe nach unten sortieren
  • ⍵[... ]: nach den angegebenen Indizes neu ordnen
  • : Holen Sie sich die einzigartigen Elemente
Marinus
quelle
3
Und doch nennen sie es irgendwie "Fortschritt", von dieser prägnanten, witzigen Sprache zu Java zu gelangen? (-:
Hippietrail
8

Python 3 - 47 43; Python 2 - 40 39

Für Python 3:

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

Für Python 2:

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

Demo:

>>> names = ["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"]
>>> f(names)
['Doe', 'Harry', 'John', 'Dick']
Blckknght
quelle
1
Ich habe versucht, dasselbe zu posten, aber hier ist eine Modifikation. f=lambda n:sorted(set(n),cmp,n.count,1)39 Zeichen
SIE
1
Hmm, ich wusste nicht, dass Sie sowohl eine Nicht-Keine- cmpFunktion als auch eine keyFunktion übergeben können. Cool.
Blckknght
1
Ein bisschen kürzer:f=lambda n:sorted(set(n),key=n.count)[::-1]
grc
Dank @grc speichert der Alien-Smiley einige Zeichen im Python 3-Fall.
Blckknght
5

Mathematica, 31

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

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

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

Ajasja
quelle
Verdammt, Sie haben mich da hingebracht: D
Yves Klett
@ YvesKlett Danke. Ich denke daran, loszuwerden Reverse, aber es Sort[GatherBy@n][[-1;;1, 1]]funktioniert nicht :). Irgendwelche Ideen?
Ajasja
4

Mathematica (26 37)

Mit 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
quelle
@garej ältere Version in Gebrauch. Als andere Antwort posten?
Yves Klett
Ich habe zu Ihren hinzugefügt, wenn Sie nichts dagegen haben ...
garej
@garej. Danke, ausgezeichnete Lösung!
Yves Klett
3

Perl 6 (36 Bytes, 35 Zeichen)

»kann durch ersetzt werden >>, wenn Sie mit UTF-8 nicht umgehen können. Ich bin mir fast sicher, dass dies kürzer sein könnte, aber die BagKlasse verhält sich (leider) relativ seltsam und ist nicht wirklich vollständig, da sie relativ neu ist (aber sie kann Argumente zählen). {}deklariert eine anonyme Funktion.

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

Beispielausgabe (von 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
quelle
3

Rubin: 34 37 Zeichen

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

(bearbeitet: vorherige 30-Zeichen-Lösung war der Hauptteil der Funktion)

neu geschrieben
quelle
Mit können Sie einige Zeichen zuschneiden f=->a{a.sort_by{|z|-a.count(z)}&a}. Das &macht eine uniq.
Histokrat
3

GolfScript, 14 Zeichen (19 als benannte Funktion, auch 14 als volles Programm)

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

Dieser Code nimmt ein Array in den Stapel und sortiert seine eindeutigen Elemente in absteigender Reihenfolge nach der Anzahl der Vorkommen. Zum Beispiel, wenn das Eingabearray ist:

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

dann wird das Ausgangsarray sein

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

Hinweis: Der obige Code ist eine bloße Folge von Anweisungen. Um daraus eine benannte Funktion zu machen, setzen Sie sie in geschweifte Klammern und weisen Sie sie einem Namen zu, wie in:

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

Um den Code in ein vollständiges Programm umzuwandeln, das eine Liste von der Standardeingabe liest (unter Verwendung der oben gezeigten Listennotation) und auf der Standardausgabe ausgibt, müssen Sie den Code voranstellen ~und anhängen `. Das [. kann in diesem Fall weggelassen werden (da wir wissen, dass es nichts anderes auf dem Stapel gibt), so dass das resultierende 14-stellige Programm sein wird:

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

Wie funktioniert es?

  • :aSpeichert eine Kopie des ursprünglichen Arrays in der Variablen azur späteren Verwendung.

  • .| berechnet die Mengenvereinigung des Arrays mit sich selbst und eliminiert Duplikate als Nebeneffekt.

  • { }$sortiert das nicht duplizierte Array mithilfe der benutzerdefinierten Sortierschlüssel, die durch den Code in geschweiften Klammern berechnet werden. Dieser Code verwendet jedes Array-Element, entfernt es mithilfe der Array-Subtraktion aus dem ursprünglichen, in gespeicherten Array aund zählt die Anzahl der verbleibenden Elemente. Somit werden die Elemente in absteigender Reihenfolge der Häufigkeit sortiert.

Ps. Sehen Sie hier für die ursprüngliche 30-Zeichen - Version.

Ilmari Karonen
quelle
Ich denke das [a\])^sollte gleichbedeutend sein mit [.;]a\-. Es ist eine gute Idee, nach der Anzahl der nicht übereinstimmenden Elemente zu sortieren.
Peter Taylor
Ach, nein: ^Duplikate kollabieren, -nicht. (Und ITYM (nicht ).) [a\](\-Würde funktionieren, aber keine Zeichen speichern.
Ilmari Karonen
2

R: 23 Zeichen

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

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

Aber es nutzt die nicht so nette Abkürzung von Tzu TRUE...

Henrik
quelle
1

wenn das hier passen könnte: 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

ODER

with cte as
(

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

select name from cte order by x desc

Sehen Sie es in Aktion

vhadalgi
quelle
1
Warum der CTE? select name from #t1 group by name order by count(*) desc
Manatwork
1

PHP, 63 62 61 Zeichen

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

Demo:

$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
quelle
werfen array_count_values()Sie einen Blick auf ... Das ist alles, was Sie verwenden müssen (einschließlich arsort())
bwoebi
array_count_values()löscht keine doppelten Werte und bestellt sie auch nicht, wie ich sehen kann.
Vereos
Es löscht die Duplikate ... Es ordnet sie einfach nicht an ... => arsort
bwoebi
@bwoebi Du hast recht. Leider ist das Schreiben um 1 Zeichen länger als diese Antwort.
Tim Seguine
Warum ist der Weg mit array_count_valueslänger? <?$u=array_count_values($_GET);arsort($u);print_r($u);Meiner Meinung nach sind es 54 Bytes
Jörg Hülsermann
1

Ruby: 59 Zeichen

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

Probelauf:

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"]
Mann bei der Arbeit
quelle
1

Mathematica, 39 Zeichen

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
quelle
1

JavaScript (ECMAScript5): 118 113 Zeichen

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
quelle
Mit Harmony Fett Pfeil Funktionen : f=n=>{m={};n.forEach(e=>m[e]=m[e]+1||1);return Object.keys(m).sort((a,b)=>m[b]-m[a])}. (Derzeit nur in Firefox.)
manatwork
Sie können m[n[i]]=-~m[n[i]]zum Inkrementieren verwenden, und Sie brauchen keine {} s um den Schleifenkörper.
Neil
1

Haskell - 53 Zeichen

import Data.List
import Data.Ord

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

Erklärung: Die ersten beiden Zeilen sind notwendige Importe, die nächste Codezeile ist die Typensignatur (in der Regel nicht notwendig), die eigentliche Funktion ist die letzte Zeile. Die Funktion sortiert die Liste nach ihrer natürlichen Reihenfolge, gruppiert gleiche Elemente in Listen, sortiert die Liste der Listen nach absteigender Größe und nimmt das erste Element in jeder Liste.

Gesamtlänge einschließlich Importe: 120

ohne Import, jedoch mit Typunterschrift: 86

Funktion selbst: 53

jgon
quelle
1

Clojure: 43 Zeichen

Funktion:

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

Demo (in 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
quelle
0

Perl

Um gegebene I / O-Spezifikationen zu erfüllen, benötige ich 120 Zeichen

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

reiner kürzester Code, indem ich einen Artikel pro Zeile nehme und einen Artikel pro Zeile drucke Ich benötige nur 55 Zeichen

$a{$_}++ while(<>);print sort{$a{$a}<=>$a{$b}}keys %a)
hildred
quelle
0

C #: 111 Zeichen

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

(innerhalb einer Klasse)

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

Damhirschkuh

Harry

John

Dick

Eine einfache Lösung mit LINQ.

paavohtl
quelle
Sie können auch die .ToList () entfernen , da die Sequenz über foreach
Adam Speight am
Das stimmt, aber dann müsste ich den Rückgabetyp in IEnumerable <string> ändern .
Paavohtl
0

R (22)

names(sort(-table(x)))

Als Funktion würde es 11 weitere Zeichen dauern.

Verwendung:

> x = c("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John")
> names(sort(-table(x)))
[1] "Doe"   "Harry" "John"  "Dick"
lambruscoAcido
quelle
Dies erfolgt über eine Variable, die vom Community-Konsens nicht zugelassen wird .
Esolanging Fruit
0

Scala (71)

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

Ungolfed:

def f(x:Array[String]) =
  (x.groupBy(a => a) map (t => (t._1, t._2.length)) toList) 
    sortBy(-_._2) map(_._1)
lambruscoAcido
quelle
0

J, 8 Bytes

~.\:#/.~

Verwendung

Die Namen werden als Array von Strings in Boxen gespeichert.

   '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│
└───┴─────┴────┴────┘

Erläuterung

~.\:#/.~   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
Meilen
quelle
0

CJam, 15 Bytes (möglicherweise nicht konkurrierend)

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

Dies kann CJam-Funktionen verwenden, nachdem diese Herausforderung veröffentlicht wurde. Ich bin zu faul zu überprüfen.

Esolanging Fruit
quelle