2012-05-01 38 views
11

我有一個包含散列數組全球化志願服務青年(即@AOH)由多個鍵排序散列數組的Perl

$arr_ref = [ { 'brand' => 'A', 
       'supplier' => 'X', 
       'PO' => '2' 
       }, 
       { 'brand' => 'B', 
       'supplier' => 'Y', 
       'PO' => '1'  
       }, 
       { 'brand' => 'B', 
       'supplier' => 'X', 
       'PO' => '2'   
       }, 
       { 'brand' => 'A', 
       'supplier' => 'X', 
       'PO' => '1' 
       }, 
       { 'brand' => 'B', 
       'supplier' => 'X', 
       'PO' => '1'   
       } 
]; 

我想將其所有三個鍵的基礎(即品牌,供應商和PO上排序)。 分揀的順序應該是品牌第一,然後是供應商,然後是最終的採購訂單。排序後

陣列全球化志願服務青年應該是:

$arr_ref = [ { 'brand' => 'A', 
       'supplier' => 'X', 
       'PO' => '1' 
       }, 
       { 'brand' => 'A', 
       'supplier' => 'X', 
       'PO' => '2' 
       }, 
       { 'brand' => 'B', 
       'supplier' => 'X', 
       'PO' => '1'   
       }, 
       { 'brand' => 'B', 
       'supplier' => 'X', 
       'PO' => '2'   
       },    
       { 'brand' => 'B', 
       'supplier' => 'Y', 
       'PO' => '1'  
       }, 
]; 

回答

34

由於<=> and cmp返回0以指示平等,這是錯誤的,因爲Perl的邏輯的布爾運算符返回判定值,而不是隻是0或1,由多個排序鍵是與or||多串在一起比較容易:

@$arr_ref = sort { $a->{brand} cmp $b->{brand} or 
        $a->{supplier} cmp $b->{supplier} or 
        $a->{PO}  <=> $b->{PO} 
       } @$arr_ref; 

我假設PO是一個數字字段,讓你用<=>的它而不是cmp

+0

謝謝CJM。它的工作原理:-) –

+0

只需添加一個有趣的案例場景。我必須將排序{...}的返回值分配給新數組,而不是使用舊數組(@ $ arr_ref)。前者返回空引用...仍然不知道爲什麼。謝謝 – mhz

+0

非常非常有用,謝謝! –

3

以下應排序的數組引用和陣列置於回$arr_ref

$arr_ref = [sort by_brand_supplier_PO @$arr_ref]; 

sub by_brand_supplier_PO { 
    $a->{brand} cmp $b->{brand} || 
    $a->{supplier} cmp $b->{supplier} || 
    $a->{PO} <=> $b->{PO} 
} 
+0

謝謝你們。有效 :-) –

1

您可以使用Sort::Key::Multi,與排序分佈::關鍵。

在這種情況下,我們使用ssikeysort,其預計,返回一個字符串,字符串和整數塊,並且排序由元組的值。 (該sssi代表字符串和i爲整數)。

use Sort::Key::Multi qw(ssikeysort); 

@$arr_ref = ssikeysort { $_->{brand}, $_->{supplier}, $_->{PO} } @$arr_ref; 

您還可以使用就地變種,它使用較少的內存:

use Sort::Key::Multi qw(ssikeysort_inplace); 

ssikeysort_inplace { $_->{brand}, $_->{supplier}, $_->{PO} } @$arr_ref;