Ordina gli elementi distinti di un elenco in ordine decrescente per frequenza


12

Scrivi una funzione che accetta un elenco o un array e restituisce un elenco di elementi distinti, ordinati in ordine decrescente per frequenza.

Esempio:

Dato:

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

Valore di ritorno atteso:

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

Code-golf o code-challenge?
Marin

Codice-golf. È stato un errore. Basta correggerlo
belvi

Risposte:


13

APL (14)

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

Questa è una funzione che accetta un elenco, ad esempio:

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

Spiegazione:

  • ∘.≡⍨⍵: confronta ogni elemento dell'array con l'altro elemento dell'array, dando una matrice
  • +⌿: somma le colonne della matrice, fornendo quante volte si verifica ogni elemento
  • : fornisce indici di tipo discendente
  • ⍵[... ]: riordina per gli indici indicati
  • : ottieni gli elementi unici

3
Eppure in qualche modo chiamano passare da questo linguaggio conciso e arguto a "progresso" di Java? (-:
hippietrail

8

Python 3 - 47 43; Python 2 - 40 39

Per Python 3:

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

Per 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
Stavo cercando di pubblicare lo stesso, ma ecco una modifica. f=lambda n:sorted(set(n),cmp,n.count,1)39 personaggi
YOU

1
Hmm, non avevo capito che potevi passare sia una funzione non-None cmpche una keyfunzione. Freddo.
Blckknght,

1
Un po 'più breve:f=lambda n:sorted(set(n),key=n.count)[::-1]
GRC

Grazie a @grc, lo smiley alieno salva alcuni personaggi nel caso Python 3.
Blckknght,

5

Mathematica, 31

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

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

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


Accidenti, mi hai portato lì: D
Yves Klett,

@YvesKlett Grazie. Sto pensando di sbarazzarmi di Reverse, ma Sort[GatherBy@n][[-1;;1, 1]]non funziona :). Qualche idea?
Ajasja,


4

Mathematica (26 37)

Con 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 versione precedente in uso. Pubblica come un'altra risposta?
Yves Klett,

Ho aggiunto al tuo se non ti dispiace ...
garej

@garej. Grazie, ottima soluzione!
Yves Klett,

3

Perl 6 (36 byte, 35 caratteri)

»può essere sostituito con >>, se non è possibile gestire UTF-8. Sono quasi sicuro che questo potrebbe essere più breve, ma la Bagclasse è relativamente strana nel suo comportamento (purtroppo), e non è davvero completa, in quanto è relativamente nuova (ma può contare argomenti). {}dichiara una funzione anonima.

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

Esempio di output (da 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

Rubino: 34 anni 37 personaggi

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

(a cura: la precedente soluzione da 30 caratteri era il corpo della funzione)


Puoi tagliare alcuni caratteri con f=->a{a.sort_by{|z|-a.count(z)}&a}. La &fa un uniq.
istocrato

3

GolfScript, 14 caratteri (19 come funzione denominata, anche 14 come programma completo)

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

Questo codice prende un array nello stack e ordina i suoi elementi univoci in ordine decrescente per numero di occorrenze. Ad esempio, se l'array di input è:

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

quindi sarà l'array di output

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

Nota: il codice sopra è una sequenza nuda di istruzioni. Per trasformarlo in una funzione con nome, avvolgilo tra parentesi graffe e assegnalo a un nome, come in:

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

In alternativa, per trasformare il codice in un programma completo che legge un elenco dall'input standard (usando la notazione dell'elenco mostrata sopra) e lo stampa sull'output standard, antepone ~e accoda `al codice. In [. questo caso è possibile omettere (poiché sappiamo che non ci sarà nient'altro nello stack), in modo che il programma di 14 caratteri risultante sarà:

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

Come funziona?

  • :asalva una copia dell'array originale nella variabile aper un uso successivo.

  • .| calcola l'unione set dell'array con se stesso, eliminando i duplicati come effetto collaterale.

  • { }$ordina l'array de-duplicato utilizzando le chiavi di ordinamento personalizzate calcolate dal codice all'interno delle parentesi graffe. Questo codice accetta ogni elemento dell'array, utilizza la sottrazione dell'array per rimuoverlo dall'array di input originale salvato ae conta il numero di elementi rimanenti. Pertanto, gli elementi vengono ordinati in ordine decrescente di frequenza.

Ps. Vedi qui per la versione originale di 30 caratteri.


Penso che [a\])^dovrebbe essere equivalente a [.;]a\-. L'ordinamento per numero di elementi non corrispondenti è una buona idea.
Peter Taylor,

Ahimè, no: ^comprime i duplicati, -no. (E ITYM (, no ).) [a\](\-Avrebbe funzionato, ma non avrebbe salvato alcun personaggio.
Ilmari Karonen,

2

R: 23 caratteri

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

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

Ma utilizza il non così bello scorciatoia di Ta TRUE...


1

se questo potesse adattarsi qui: 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

O

with cte as
(

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

select name from cte order by x desc

vederlo in azione


1
Perché il CTE? select name from #t1 group by name order by count(*) desc
arte

1

PHP, 63 62 61 caratteri

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 )

dai un'occhiata a array_count_values()... Questo è tutto ciò che devi usare (incluso arsort())
bwoebi

array_count_values()non elimina i valori duplicati, né li ordina, come posso vedere.
Vereos,

Elimina i duplicati ... Semplicemente non li ordina ... => arsort
bwoebi

@bwoebi Hai ragione. Purtroppo scrivere in questo modo è più lungo di 1 carattere di questa risposta.
Tim Seguine,

Perché la strada è array_count_valuespiù lunga? <?$u=array_count_values($_GET);arsort($u);print_r($u);sono 54 byte secondo me
Jörg Hülsermann il

1

Rubino: 59 caratteri

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

Esecuzione di esempio:

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 personaggi

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 caratteri

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/


Con Harmony di funzioni grasso freccia : f=n=>{m={};n.forEach(e=>m[e]=m[e]+1||1);return Object.keys(m).sort((a,b)=>m[b]-m[a])}. (Attualmente solo in Firefox.)
manatwork

Puoi usare m[n[i]]=-~m[n[i]]per incrementare e non hai bisogno di {} s attorno al corpo del loop.
Neil,

1

Haskell - 53 personaggi

import Data.List
import Data.Ord

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

Spiegazione: le prime due righe sono importazioni necessarie, la riga di codice successiva è la firma del tipo (generalmente non necessaria), la funzione effettiva è l'ultima riga. La funzione ordina l'elenco in base al suo ordinamento naturale, raggruppa elementi uguali in elenchi, ordina l'elenco di elenchi in ordine decrescente di dimensione e accetta il primo elemento in ciascun elenco.

lunghezza totale comprese le importazioni: 120

senza importazioni ma con firma del tipo: 86

funzione stessa: 53


1

Clojure: 43 caratteri

Funzione:

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

Demo (in sostituzione):

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

per soddisfare le specifiche di I / O ho bisogno di 120 caratteri

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

puro codice abbreviato prendendo un articolo per riga e stampando un articolo per riga ho solo bisogno di 55 caratteri

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

0

C #: 111 caratteri

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

(all'interno di una 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);
}

daino

Harry

John

Cazzo

Una soluzione semplice che utilizza LINQ.


Puoi anche rimuovere .ToList () , poiché la sequenza viene enumerata tramite foreach
Adam Speight,

È vero, ma poi dovrei cambiare il tipo restituito in IEnumerable <stringa> .
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 byte

~.\:#/.~

uso

I nomi sono memorizzati come una matrice di stringhe inscatolate.

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

Spiegazione

~.\:#/.~   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 byte (possibilmente non concorrenziale)

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

Questo può utilizzare le funzionalità di CJam dopo che questa sfida è stata pubblicata. Sono troppo pigro per controllare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.