2013-02-06 11 views
9

Próbuję wykonać następujące czynności. Mam predefiniowaną listę, która będzie używana jako "zamówienie przez" na danej liście.Jak posortować listę dla danego zamówienia?

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

Próbowałem nieskończonych sposobów sortowania i nie dostałem tego, co chcę. Szukałem w Google i tutaj, ale nie znalazłem odpowiedzi.

@list muszą być klasyfikowane w ten sposób:

sort @list using %orderby 

druk, że chcę po sortowania:

car, boat, chicken, mouse 

BTW, może @list zostały zduplikowane wpisy:

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

W takim przypadku wydruk musi być:

car, car, boat, chicken, mouse, mouse

Czy macie na to rozwiązanie? lub może inne podejście. Dzięki!

+1

Re aktualizacją, mój rozwiązania obsługują duplikaty. – ikegami

+0

Tak, testowałem to! Jeszcze raz! – Jonathan

Odpowiedz

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; 

Albo jeśli chcesz bałagan z umysłach,

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

Tablicą do posortowania jest 'list', a nie' orderby'. – Toto

+0

oops, literówka. Naprawiony. – ikegami

+0

o mój, to było szybkie. Teraz spróbuję zrozumieć mapę. Dziękuję Ci! – Jonathan

0

Z pewnością, jeśli masz listę wszystkich możliwych pozycji w porządku, a mniejsza lista elementów, które chcesz aby wybrać, to jest właściwie problem z wyborem, a nie problem z sortowaniem?

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

Działa w O (n) czas zamiast O (n log n) też :)

+0

Jest to zasadniczo to samo, co drugie z rozwiązań opublikowanych 4 dni wcześniej, z wyjątkiem moich, ponieważ obsługuje duplikaty, a twoje nie spełnia specyfikacji OP, ponieważ tak nie jest. – ikegami

0

sortowanie pozycyjne jest dobrym wyborem dla tego przypadku:

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