2013-02-06 45 views
9

Tôi đang cố gắng thực hiện những việc sau. Tôi có một danh sách được xác định trước để được sử dụng như một "thứ tự" trên một danh sách nhất định.Cách sắp xếp danh sách theo một thứ tự nhất định?

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

Tôi đã thử các cách vô hạn để sắp xếp và tôi không nhận được những gì tôi muốn. Tôi đã tìm kiếm trên google, và ở đây, nhưng tôi đã không tìm thấy câu trả lời.

@list cần phải được sắp xếp theo cách đó:

sort @list using %orderby 

Việc in ấn mà tôi muốn sau khi sắp xếp: mục

car, boat, chicken, mouse 

BTW, @list thể đã nhân đôi:

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

Trong trường hợp đó, bản in cần phải là:

car, car, boat, chicken, mouse, mouse

Các bạn có giải pháp cho điều đó không? hoặc có thể là cách tiếp cận khác. Cảm ơn !!

+1

Re cập nhật của bạn, của tôi các giải pháp xử lý các bản sao. – ikegami

+0

có, tôi đã thử nghiệm điều đó! Thx lần nữa! – Jonathan

Trả lời

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; 

Hoặc nếu bạn muốn gây rối với đầu óc con người,

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

Mảng được sắp xếp là 'danh sách', không phải' thứ tự'. – Toto

+0

oops, lỗi đánh máy. Đã sửa. – ikegami

+0

ôi, nhanh quá. Bây giờ tôi sẽ cố gắng hiểu bản đồ. cảm ơn bạn! – Jonathan

0

Chắc chắn nếu bạn có một danh sách của tất cả các mặt hàng tiềm năng theo thứ tự, và một danh sách nhỏ của các mục mà bạn muốn để chọn, thì đây thực sự là vấn đề lựa chọn và không phải là vấn đề phân loại?

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

Chạy trong thời gian O (n) thời gian chứ không phải là O (n log n) quá :)

+0

Về cơ bản giống như giải pháp thứ hai tôi đã đăng 4 ngày trước đó, ngoại trừ của tôi tốt hơn bởi vì nó xử lý các bản sao, và bạn không đáp ứng thông số kỹ thuật của OP vì nó không. – ikegami

0

Radix sort là một lựa chọn tốt cho trường hợp đó:

use Sort::Key::Radix qw(ukeysort); 
@sorted = ukeysort { $orderby{$_} } @data; 
Các vấn đề liên quan