2010-08-27 102 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