2013-02-06 16 views
9

Ich versuche folgendes zu tun. Ich habe eine vordefinierte Liste, die als "Order by" für eine gegebene Liste verwendet werden kann.Wie sortiere ich eine Liste mit einer bestimmten Reihenfolge?

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'); 

Ich versuchte unendliche Möglichkeiten, es zu sortieren, und ich habe nicht bekommen, was ich will. Ich habe auf Google gesucht, und hier, aber ich habe die Antwort nicht gefunden.

@list Bedarf auf diese Weise sortiert werden:

sort @list using %orderby 

Der Druck, den ich nach der Art wollen:

car, boat, chicken, mouse 

BTW, können @liste Einträge dupliziert haben:

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

In diesem Fall muss der Druck:

sein 10
car, car, boat, chicken, mouse, mouse

Haben Sie eine Lösung dafür? oder vielleicht ein anderer Ansatz. Danke !!

+1

Re Ihr Update, mein Lösungen behandeln Duplikate. – ikegami

+0

ja, das habe ich getestet! Danke nochmal! – Jonathan

Antwort

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; 

Oder wenn Sie wollen Chaos mit den Köpfen der Menschen,

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

Das zu sortierende Array ist 'list', nicht' orderby'. – Toto

+0

oops, typo. Fest. – ikegami

+0

Oh mein Gott, das war schnell. Jetzt werde ich versuchen, Karte zu verstehen. Danke! – Jonathan

0

Sicher, wenn Sie eine Liste aller potenziellen Produkte haben, um, und eine kleinere Liste der Artikel, die Sie wollen auszuwählen, dann ist das eigentlich ein Auswahlproblem und kein Sortierproblem?

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

Runs in O (n) Zeit statt O (n log n) zu :)

+0

Das ist im Grunde das gleiche wie die zweite der Lösungen, die ich 4 Tage zuvor gepostet habe, außer dass meine besser ist, weil es Duplikate verarbeitet, und deins nicht die OP-Spezifikationen erfüllt, weil es nicht tut. – ikegami

0

Radix Art ist eine gute Wahl für diesen Fall:

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