Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting an Array of Hash by multiple keys Perl

Tags:

I have an array referance containing hashes (i.e. @AOH)

$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'                          } ]; 

I want to sort it on the basis of all three keys (i.e. brand, supplier and PO). Order of sorting should be brand first, then supplier and then finally on PO.

array referance after sorting should be:

$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'                      }, ]; 
like image 212
Manoj Shekhawat Avatar asked May 01 '12 08:05

Manoj Shekhawat


2 Answers

Since <=> and cmp return 0 to indicate equality, and that's false, and because Perl's logical Boolean operators return the deciding value instead of just 0 or 1, sorting by multiple keys is as easy as stringing multiple comparisons together with or or ||:

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

I'm assuming that PO is a numeric field, so you use <=> for it instead of cmp.

like image 75
cjm Avatar answered Oct 05 '22 12:10

cjm


The following should sort the array reference and place the array back into the $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} } 
like image 29
mttrb Avatar answered Oct 05 '22 12:10

mttrb