2013-02-06 4 views
9

Sto provando a fare quanto segue. Ho un elenco predefinito da utilizzare come "ordina per" su una lista data.Come ordinare una lista con un determinato ordine?

my @orderby = ('car', 'boat', 'chicken', 'cat', 'dog', 'mouse'); 
    or 
my %orderby = ('car' => 0, 'boat' => 1, 'chicken' => 2, 'cat' => 3, 'dog' => 4, 'mouse' => 5); 

my @list = ('boat', 'car', 'mouse', 'chicken'); 

Ho provato infiniti modi per ordinarlo e non ho ottenuto quello che volevo. Ho cercato su google e qui, ma non ho trovato la risposta.

@list bisogno di essere ordinata in questo modo:

sort @list using %orderby 

La stampa che voglio dopo l'ordinamento: voci

car, boat, chicken, mouse 

BTW, @List può aver duplicato:

my @list = ('boat', 'car', 'mouse', 'chicken', 'mouse', 'car');

In questo caso, la stampa deve essere:

car, car, boat, chicken, mouse, mouse

Avete una soluzione per questo? o forse un altro approccio. Grazie !!

+1

Re l'aggiornamento, la mia le soluzioni gestiscono i duplicati. – ikegami

+0

sì, l'ho provato! Di nuovo! – Jonathan

risposta

12
my @orderby = qw(car boat chicken cat dog mouse); 
my @list = qw(boat car mouse chicken); 

my %orderby = map { $orderby[$_] => $_ } 0..$#orderby; 

my @sorted = sort { $orderby{$a} <=> $orderby{$b} } @list; 

Oppure, se si vuole pasticciare con la mente delle persone,

my @orderby = qw(car boat chicken cat dog mouse); 
my @list = qw(boat car mouse chicken); 

my %counts; ++$counts{$_} for @list; 
my @sorted = map { ($_) x ($counts{$_}||0) } @orderby; 
+1

L'array da ordinare è 'list', non' orderby'. – Toto

+0

oops, errore di battitura. Fisso. – ikegami

+0

oh mio Dio, è stato veloce. Ora proverò a capire la mappa. grazie! – Jonathan

0

Sicuramente se si dispone di un elenco di tutti i potenziali elementi in ordine, e un elenco più piccolo degli elementi che si desidera per selezionare, allora questo è in realtà un problema di selezione e non un problema di classificazione?

my %items = map { $_ => 1 } @list; 
my @items = grep { $items{$_} } @orderby; 

Viene eseguito in O (n), piuttosto che O (n log n) troppo :)

+0

Questo è praticamente lo stesso del secondo delle soluzioni che ho postato 4 giorni prima, eccetto il mio è meglio perché gestisce i duplicati, e il tuo non soddisfa le specifiche dell'OP perché non lo fa. – ikegami

0

Radix sort è una buona scelta per questo caso:

use Sort::Key::Radix qw(ukeysort); 
@sorted = ukeysort { $orderby{$_} } @data;