2013-02-06 24 views
9

私は次のことをしようとしています。私は、所定のリスト上で「順序付け」として使用される予め定義されたリストを有する。指定された順序でリストをソートする方法は?

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

私はそれを並べ替える無限の方法を試みたが、私は何をしたいのか分からなかった。私はGoogleで検索しましたが、ここでは答えが見つかりませんでした。

@listそのようにソートする必要があります

sort @list using %orderby 

私は、ソート後にしたい印刷:

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

car, boat, chicken, mouse 

ところで、@listは、エントリを重複していることができます

この場合、印刷する必要があります:

car, car, boat, chicken, mouse, mouse

皆さんには解決策がありますか? か、別のアプローチかもしれません。 ありがとうございます!確かに

+1

ソリューションは重複を処理します。 – ikegami

+0

はい、私はそれをテストしました!再びThx! – Jonathan

答えて

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; 

それとも、人々の心を台無しにする場合は、

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

ソートする配列は 'orderby'ではなく' list'です。 – Toto

+0

oops、typo。一定。 – ikegami

+0

ああ、それは速かった。今私はマップを理解しようとします。ありがとうございました! – Jonathan

0

あなたは順番にすべての潜在的な項目のリスト、およびあなたが望む項目の小さなリストを持っている場合選択するには、これは実際に選択問題であり、ソートの問題ではありませんか? Oで

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

ラン(n)を過ぎるというOよりも(n log n)時間:)

+0

これは、私が4日前に投稿したソリューションの2番目のものと基本的に同じですが、私が重複を処理し、OPのスペックを満たしていないことを除けば、OPのスペックは満たされません。 – ikegami

0

基数ソートは、そのような場合に適しています:私、あなたの更新再

use Sort::Key::Radix qw(ukeysort); 
@sorted = ukeysort { $orderby{$_} } @data; 
関連する問題