2012-04-25 219 views
4

伪代码:的Perl:排序基于特定列多列的二维阵列

my @unsortedArray = { ["Harry", 10], ["Tim", 8], ["Joe", 3]}; 
my @sortedArray = ????? 

最终sortedArray应当基于COL-2(整数),照顾1对1的关系的排序与“人的名字”(col-1)。最终的结果应该是这样的:

sortedArray should be { ["Joe", 3], ["Tim", 8], ["Harry", 10] }; 
+0

'@array = {...}'(几乎总是)不正确的语法。使用'@array =(...)'分配给一个数组。 – mob 2012-04-25 15:09:20

+0

@mob:我想知道当你提到几乎*时你有什么边缘情况?:) – Zaid 2012-04-25 16:08:27

+0

@Zaid:'@array_containing_a_single_hashref = {...}' – mob 2012-04-25 16:10:41

回答

7

你可以给一个谓词sort,那就是:这是评价比较列表的元素的功能。

my @unsorted = (["Harry", 10], ["Tim", 8], ["Joe", 3]); 

my @sorted = sort { $a->[1] <=> $b->[1] } @unsorted; 

在谓词(在大括号中的表达式),并且$a$b被比较的外列表中的元素。

sort只关心一维列表,所以它不会混淆外部列表元素的内部结构。所以姓名和号码之间的关系可以毫不费力地保留下来。

有关更多详细信息,请参阅perldoc -f sortperldoc perlop

+0

my @sorted = sort {$ a - > [1]> $ b - > [1]} @unsorted; 更容易理解 – askovpen 2012-04-25 15:33:13

+0

谢谢。有效。我只是使用“排序”,这是排序第二列。 – Mike 2012-04-25 15:33:16

+1

@Mike没有那么错 - 香草'sort'的谓词更像'{“$ a”cmp“$ b”}',所以你会比较''ARRAY(0x2229d48)“'和'' ARRAY(0x2229d98)“'。任何与第二列的排序相似都是巧合。 – mob 2012-04-25 16:08:22

1

一种更有效的解决方案,尤其是对于较大的阵列,可以是使用List::UtilsBy::nsort_by

use List::UtilsBy qw(nsort_by); 

my @unsorted = (["Harry", 10], ["Tim", 8], ["Joe", 3]); 

my @sorted = nsort_by { $_->[1] } @unsorted; 

尽管在小的情况下的开销可能不会被注意到,对于更复杂的功能O(n log n)密钥提取成本变更高,并且更优选的是提取每个值的“分类键”仅一次,这是nsort_by所做的。

+2

另请参阅:[Sort :: Key](http://p3rl.org/Sort::Key) – daxim 2012-04-25 21:38:44