Trier les éléments distincts d'une liste par ordre décroissant par fréquence

12

Écrivez une fonction qui prend une liste ou un tableau et renvoie une liste des éléments distincts, triés par ordre décroissant par fréquence.

Exemple:

Donné:

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

Valeur de retour attendue:

["Doe","Harry","John","Dick"]
belvi
la source
Code-golf ou code-challenge?
marinus
Code-golf. C'était une erreur. Juste le corriger
belvi

Réponses:

13

APL (14)

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

Il s'agit d'une fonction qui prend une liste, par exemple:

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

Explication:

  • ∘.≡⍨⍵: comparer chaque élément du tableau à chaque autre élément du tableau, donnant une matrice
  • +⌿: additionne les colonnes de la matrice, donnant combien de fois chaque élément apparaît
  • : donner des indices de type descendant
  • ⍵[... ]: réorganiser par les indices donnés
  • : obtenez les éléments uniques
marinus
la source
3
Et pourtant, d'une manière ou d'une autre, ils appellent le passage de ce langage spirituel concis au «progrès» Java? (-:
hippietrail
8

Python 3 - 47 43; Python 2-40 39

Pour Python 3:

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

Pour Python 2:

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

Démo:

>>> names = ["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"]
>>> f(names)
['Doe', 'Harry', 'John', 'Dick']
Blckknght
la source
1
J'essayais de poster le même, mais voici une modification. f=lambda n:sorted(set(n),cmp,n.count,1)39 personnages
VOUS du
1
Hmm, je ne savais pas que vous pouviez passer à la fois une fonction non nulle cmpet une keyfonction. Cool.
Blckknght
1
Un peu plus court:f=lambda n:sorted(set(n),key=n.count)[::-1]
grc
Merci @grc, le smiley extraterrestre enregistre certains personnages dans le cas Python 3.
Blckknght
5

Mathematica, 31

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

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

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

Ajasja
la source
Bon sang, tu m'as eu là: D
Yves Klett
@YvesKlett Merci. Je pense à m'en débarrasser Reverse, mais Sort[GatherBy@n][[-1;;1, 1]]ça ne marche pas :). Des idées?
Ajasja
4

Mathematica (26 37)

Avec 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
la source
@garej ancienne version utilisée. Poster comme autre réponse?
Yves Klett
Je l'ai ajouté au vôtre si cela ne vous dérange pas ...
garej
@garej. Merci, excellente solution!
Yves Klett
3

Perl 6 (36 octets, 35 caractères)

»peut être remplacé par >>, si vous ne pouvez pas gérer UTF-8. Je suis presque sûr que cela pourrait être plus court, mais la Bagclasse est relativement étrange dans son comportement (malheureusement), et n'est pas vraiment complète, car elle est relativement nouvelle (mais elle peut compter des arguments). {}déclare une fonction anonyme.

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

Exemple de sortie (de 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
la source
3

Rubis: 34 37 personnages

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

(édité: la solution précédente de 30 caractères était le corps de la fonction)

réécrit
la source
Vous pouvez couper quelques caractères avec f=->a{a.sort_by{|z|-a.count(z)}&a}. Le &fait un uniq.
histocrate
3

GolfScript, 14 caractères (19 comme fonction nommée, également 14 comme programme complet)

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

Ce code prend un tableau sur la pile et trie ses éléments uniques par ordre décroissant par nombre d'occurrences. Par exemple, si le tableau d'entrée est:

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

alors le tableau de sortie sera

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

Remarque: Le code ci-dessus est une simple séquence d'instructions. Pour la transformer en fonction nommée, enveloppez-la entre accolades et affectez-la à un nom, comme dans:

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

Alternativement, pour transformer le code en un programme complet qui lit une liste à partir de l'entrée standard (en utilisant la notation de liste illustrée ci-dessus) et l'imprime sur la sortie standard, ~ajoutez et ajoutez `au code. Le [. peut être omis dans ce cas (puisque nous savons qu'il n'y aura rien d'autre sur la pile), de sorte que le programme résultant à 14 caractères sera:

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

Comment ça marche?

  • :aenregistre une copie du tableau d'origine dans la variable apour une utilisation ultérieure.

  • .| calcule l'union définie du tableau avec lui-même, éliminant les doublons comme effet secondaire.

  • { }$trie le tableau dédoublonné à l'aide des clés de tri personnalisées calculées par le code à l'intérieur des accolades. Ce code prend chaque élément du tableau, utilise la soustraction du tableau pour le supprimer du tableau d'entrée d'origine enregistré dans a, et compte le nombre d'éléments restants. Ainsi, les éléments sont triés par ordre décroissant de fréquence.

Ps. Voir ici pour la version originale de 30 caractères.

Ilmari Karonen
la source
Je pense que cela [a\])^devrait être équivalent à [.;]a\-. Trier par nombre d'éléments non correspondants est une bonne idée.
Peter Taylor
Hélas, non: ^effondre les doublons, -non. (Et ITYM (, non ).) Fonctionnerait , [a\](\-mais ne sauverait aucun caractère.
Ilmari Karonen
2

R: 23 caractères

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

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

Mais il utilise le raccourci pas si sympa de Tto TRUE...

Henrik
la source
1

si cela pouvait convenir ici: 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

OU

with cte as
(

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

select name from cte order by x desc

le voir en action

vhadalgi
la source
1
Pourquoi le CTE? select name from #t1 group by name order by count(*) desc
manatwork du
1

PHP, 63 62 61 caractères

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

Démo:

$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
la source
jetez un oeil à array_count_values()… C'est tout ce que vous avez à utiliser (y compris arsort())
bwoebi
array_count_values()ne supprime pas les valeurs dupliquées, ni les ordonne, comme je peux le voir.
Vereos
Il supprime les doublons… Il ne les commande tout simplement pas… => arsort
bwoebi
@bwoebi Vous avez raison. Malheureusement, l'écrire de cette façon est 1 caractère plus long que cette réponse.
Tim Seguine du
Pourquoi le chemin est-il array_count_valuesplus long? <?$u=array_count_values($_GET);arsort($u);print_r($u);sont 54 octets à mon avis
Jörg Hülsermann
1

Ruby: 59 caractères

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

Exemple d'exécution:

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"]
homme au travail
la source
1

Mathematica, 39 caractères

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

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

f@names

{Biche, Harry, John, Dick}

Chris Degnen
la source
1

JavaScript (ECMAScript5): 118 113 caractères

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
la source
Avec Harmony fonctions fléchées de la graisse : f=n=>{m={};n.forEach(e=>m[e]=m[e]+1||1);return Object.keys(m).sort((a,b)=>m[b]-m[a])}. (Actuellement uniquement dans Firefox.)
Manatwork
Vous pouvez utiliser m[n[i]]=-~m[n[i]]pour incrémenter et vous n'avez pas besoin de {} autour du corps de la boucle.
Neil
1

Haskell - 53 personnages

import Data.List
import Data.Ord

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

Explication: les deux premières lignes sont des importations nécessaires, la ligne de code suivante est la signature de type (généralement pas nécessaire), la fonction réelle est la dernière ligne. La fonction trie la liste par son ordre naturel, regroupe les éléments égaux en listes, trie la liste des listes par taille décroissante et prend le premier élément de chaque liste.

longueur totale, importations comprises: 120

sans importations mais avec signature de type: 86

fonctionner lui-même: 53

jgon
la source
1

Clojure: 43 caractères

Une fonction:

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

Démo (en 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
la source
0

Perl

pour répondre aux spécifications d'E / S données, j'ai besoin de 120 caractères

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

code le plus court en prenant un élément par ligne et en imprimant un élément par ligne, je n'ai besoin que de 55 caractères

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

C #: 111 caractères

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

(à l'intérieur d'une classe)

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

Biche

Harry

John

Queue

Une solution simple utilisant LINQ.

paavohtl
la source
Vous pouvez également supprimer le .ToList () , car la séquence est énumérée via foreach
Adam Speight
C'est vrai, mais je devrais alors changer le type de retour en IEnumerable <string> .
paavohtl
0

R (22)

names(sort(-table(x)))

En tant que fonction, il faudrait 11 caractères supplémentaires.

Usage:

> x = c("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John")
> names(sort(-table(x)))
[1] "Doe"   "Harry" "John"  "Dick"
lambruscoAcido
la source
Cela prend l'entrée d'une variable, qui n'est pas autorisée par le consensus de la communauté .
Esolanging Fruit
0

Scala (71)

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

Non golfé:

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

J, 8 octets

~.\:#/.~

Usage

Les noms sont stockés sous forme de tableau de chaînes encadrées.

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

Explication

~.\:#/.~   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
miles
la source
0

CJam, 15 octets (éventuellement non concurrents)

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

Cela peut utiliser les fonctionnalités CJam après la publication de ce défi. Je suis trop paresseux pour vérifier.

Esolanging Fruit
la source