Ordenar los distintos elementos de una lista en orden descendente por frecuencia

12

Escriba una función que tome una lista o matriz y devuelva una lista de los elementos distintos, ordenados en orden descendente por frecuencia.

Ejemplo:

Dado:

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

Valor de retorno esperado:

["Doe","Harry","John","Dick"]
belvi
fuente
¿Código de golf o código de desafío?
marinus
Código de golf. Eso fue un error. Solo corrígelo
belvi el

Respuestas:

13

APL (14)

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

Esta es una función que toma una lista, por ejemplo:

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

Explicación:

  • ∘.≡⍨⍵: compara cada elemento en la matriz con el otro elemento en la matriz, dando una matriz
  • +⌿: suma las columnas de la matriz, indicando cuántas veces ocurre cada elemento
  • : dar índices de tipo descendente
  • ⍵[... ]: reordenar por los índices dados
  • : obtener los elementos únicos
marinus
fuente
3
¿Y sin embargo, de alguna manera, llaman pasar de este lenguaje ingenioso conciso a Java "progreso"? (-:
hippietrail
8

Python 3 - 47 43; Python 2 - 40 39

Para Python 3:

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

Para Python 2:

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

Manifestación:

>>> names = ["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"]
>>> f(names)
['Doe', 'Harry', 'John', 'Dick']
Blckknght
fuente
1
Estaba tratando de publicar lo mismo, pero aquí hay una modificación. f=lambda n:sorted(set(n),cmp,n.count,1)39 caracteres
1
Hmm, no me di cuenta de que podías pasar una función que no sea Ninguna cmpy una keyfunción. Frio.
Blckknght
1
Un poco más corto:f=lambda n:sorted(set(n),key=n.count)[::-1]
grc
Gracias @grc, el smiley alienígena salva algunos personajes en el caso de 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"})

Ajasja
fuente
Maldición, me tienes allí: D
Yves Klett
@YvesKlett Gracias. Estoy pensando en deshacerme de él Reverse, pero Sort[GatherBy@n][[-1;;1, 1]]no funciona :). ¿Algunas ideas?
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&]
Yves Klett
fuente
@garej versión anterior en uso. Publicar como otra respuesta?
Yves Klett
He añadido a la tuya si no te importa ...
garej
@garej. Gracias, excelente solución!
Yves Klett
3

Perl 6 (36 bytes, 35 caracteres)

»se puede reemplazar con >>, si no puede manejar UTF-8. Estoy casi seguro de que esto podría ser más corto, pero la Bagclase es relativamente extraña en su comportamiento (lamentablemente) y no está realmente completa, ya que es relativamente nueva (pero puede contar argumentos). {}declara una función anónima.

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

Salida de muestra (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
fuente
3

Rubí: 34 37 caracteres

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

(editado: la solución anterior de 30 caracteres era el cuerpo de la función)

reescrito
fuente
Puedes recortar algunos caracteres con f=->a{a.sort_by{|z|-a.count(z)}&a}. El &hace un uniq.
histocrat
3

GolfScript, 14 caracteres (19 como función con nombre, también 14 como programa completo)

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

Este código toma una matriz en la pila y ordena sus elementos únicos en orden descendente por número de ocurrencias. Por ejemplo, si la matriz de entrada es:

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

entonces la matriz de salida será

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

Nota: El código anterior es una secuencia simple de declaraciones. Para convertirlo en una función con nombre, envuélvalo entre llaves y asígnelo a un nombre, como en:

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

Alternativamente, para convertir el código en un programa completo que lea una lista desde la entrada estándar (usando la notación de lista que se muestra arriba) e imprima en la salida estándar, anteponga ~y agregue `el código. Se [. puede omitir en este caso (ya que sabemos que no habrá nada más en la pila), de modo que el programa resultante de 14 caracteres será:

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

¿Como funciona?

  • :aguarda una copia de la matriz original en la variable apara su uso posterior.

  • .| calcula la unión del conjunto de la matriz consigo mismo, eliminando duplicados como efecto secundario.

  • { }$ordena la matriz desduplicada utilizando las claves de clasificación personalizadas calculadas por el código dentro de las llaves. Este código toma cada elemento de la matriz, utiliza la resta de la matriz para eliminarlo de la matriz de entrada original guardada ay cuenta el número de elementos restantes. Por lo tanto, los elementos se ordenan en orden decreciente de frecuencia.

PD. Vea aquí la versión original de 30 caracteres.

Ilmari Karonen
fuente
Creo que eso [a\])^debería ser equivalente a [.;]a\-. Ordenar por número de elementos que no coinciden es una buena idea.
Peter Taylor
Por desgracia, no: ^colapsa duplicados, -no. (Y ITYM (, no ).) Funcionaría , [a\](\-pero no salvaría ningún personaje.
Ilmari Karonen
2

R: 23 caracteres

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

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

Pero utiliza el no tan buen atajo de Ta TRUE...

Henrik
fuente
1

si esto pudiera encajar aquí: 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

verlo en acción

vhadalgi
fuente
1
¿Por qué el CTE? select name from #t1 group by name order by count(*) desc
manatwork
1

PHP, 63 62 61 caracteres

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

Manifestación:

$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
fuente
echa un vistazo a array_count_values()... Eso es todo lo que tienes que usar (incluido arsort())
bwoebi
array_count_values()no elimina valores duplicados, ni los ordena, como puedo ver.
Vereos
Elimina los duplicados ... Simplemente no los ordena ... => arsort
bwoebi
@bwoebi Tienes razón. Desafortunadamente, escribirlo de esa manera es 1 carácter más largo que esta respuesta.
Tim Seguine
¿Por qué es el camino con array_count_valuesmás tiempo? <?$u=array_count_values($_GET);arsort($u);print_r($u);son 54 bytes en mi opinión
Jörg Hülsermann
1

Ruby: 59 caracteres

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

Ejecución de muestra:

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"]
hombre trabajando
fuente
1

Mathematica, 39 caracteres

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

JavaScript (ECMAScript5): 118 113 caracteres

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
fuente
Con la armonía de las funciones de la grasa de flecha : f=n=>{m={};n.forEach(e=>m[e]=m[e]+1||1);return Object.keys(m).sort((a,b)=>m[b]-m[a])}. (Actualmente solo en Firefox.)
manatwork
Puede usar m[n[i]]=-~m[n[i]]para incrementar, y no necesita {} s alrededor del cuerpo del bucle.
Neil
1

Haskell - 53 Personajes

import Data.List
import Data.Ord

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

Explicación: las dos primeras líneas son importaciones necesarias, la siguiente línea de código es la firma de tipo (generalmente no es necesaria), la función real es la última línea. La función clasifica la lista por su orden natural, agrupa elementos iguales en listas, ordena la lista de listas por tamaño descendente y toma el primer elemento de cada lista.

longitud total incluidas las importaciones: 120

sin importaciones pero con firma de tipo: 86

función en sí: 53

jgon
fuente
1

Clojure: 43 caracteres

Función:

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

Demostración (en respuesta):

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
fuente
0

Perl

para cumplir con las especificaciones de E / S, necesito 120 caracteres

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

código más corto puro tomando un artículo por línea e imprimiendo un artículo por línea Solo necesito 55 caracteres

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

C #: 111 caracteres

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

(dentro de una clase)

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

Gama

Harry

John

Polla

Una solución simple usando LINQ.

paavohtl
fuente
También puede eliminar .ToList () , ya que la secuencia se enumera a través del foreach
Adam Speight
Eso es cierto, pero luego tendría que cambiar el tipo de retorno a IEnumerable <string> .
paavohtl
0

R (22)

names(sort(-table(x)))

Como función, tomaría 11 caracteres más.

Uso:

> x = c("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John")
> names(sort(-table(x)))
[1] "Doe"   "Harry" "John"  "Dick"
lambruscoAcido
fuente
Esto toma información de una variable, que no está permitida por el consenso de la comunidad .
Esolanging Fruit
0

Scala (71)

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

Sin golf:

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

J, 8 bytes

~.\:#/.~

Uso

Los nombres se almacenan como una matriz de cadenas en caja.

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

Explicación

~.\:#/.~   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
millas
fuente
0

CJam, 15 bytes (posiblemente no compitiendo)

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

Esto puede usar las funciones de CJam desde que se publicó este desafío. Soy demasiado vago para comprobarlo.

Fruta Esolanging
fuente