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"]

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

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']

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


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&]

@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

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)


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.


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...


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


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 )

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"]

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}


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/


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


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")

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)

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.


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

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)

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

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.