2010-08-27 114 views
6

我有散列的散列,像这样:如何映射(并排序)散列哈希值?

 
%hash = (a => { b => 1, c =>2, d => 3}, 
      a1 => { b => 11, c =>12, d => 13}, 
      a2 => { b => 21, c =>22, d => 23}) 

我要提取的“b”的元件,并把它放到一个数组。现在,我正在通过哈希循环来做到这一点,但我认为我可以通过使用map来改善效率。我敢肯定,如果这是哈希的数组,我会使用这样的:

 
@hasharray = ({ b => 1, c =>2, d => 3}, 
       { b => 11, c =>12, d => 13}, 
       { b => 21, c =>22, d => 23}) 
@array = map { ($_->{b} => $_) } @hasharray 

原谅我,如果我错了,我仍然在学习地图是如何工作的。但是我想知道的是,我将如何去映射哈希散列?这甚至可以使用地图?我还没有找到任何这样做的例子。

更好的是,这段代码的下一步是对数组进行排序。我非常确定这是可能的,但是我没有足够的智能使用地图来自己弄清楚。我将如何一举完成这一切?

谢谢。 赛斯

回答

11

这种提取物和排序所有的 “B” s:

my @array = sort { $a <=> $b } map $_->{b}, values %hash; 
+0

这很好,正是我所期待的。我用这个替换了26行代码,并将该函数的性能从O(n)改进为O(1)。谢谢! – sgsax 2010-08-27 16:15:12

+1

好吧,它仍然需要迭代散列的值并对它们进行排序,所以它实际上并不是O(1)。 – Corey 2010-08-27 21:48:41

1

把你的第二个解决方案,并替换为values %hash@hasharray

@array = map { ($_->{b} => $_) } values %hash; 

(不要忘了;终止语句)

3

这填充@array与数组引用的排序列表,每个包含值b和它来自的hashref。

my @array = sort {$$a[0] <=> $$b[0]} 
      map { [$$_{b} => $_] } 
      values %hash; 

my @sorted_hashes = map {$$_[1]} @array; 
+1

'$ a - > [0]'比'$$ a [0]'更容易阅读;类似'$ _-> {b}'而不是'$$ _ {b}'。 – 2010-08-27 15:22:06

+0

对数字进行排序时,最好使用'<=>'运算符而不是'cmp'。 – 2010-08-27 15:26:05

+0

@eugene =>好点,修复。 @Philip =>我更喜欢双重签名有两个原因。首先,它具有其他形式的解引用,例如'@ $ a [1,2]'。其次,' - >'运算符用于方法调用,所以我更喜欢只在调用代码的情况下使用它。 – 2010-08-27 16:27:36