2011-04-05 55 views
4

我有一個哈希數組。我想要基於另一個鍵的唯一性的那些散列鍵中的值的列表。我可以避免引用+取消引用從映射操作返回的散列嗎?

my @obs = ({ 
    value => 'three', 
    id => 3 
},{ 
    value => 'one-2', 
    id => 1 
},{ 
    value => 'one', 
    id => 1 
}); 
# This works, prints "one\nthree" 
say for values %{{ map { $_->{id} => $_->{value} } @obs }}; 

我可以避開map附近的參考+解除引用位嗎?起初,我試着打電話是values直接從map的回報,但Perl將不會有它:

ARG 1的類型到值必須是哈希(未映射迭代器)在腳本\ workbench.pl線55,靠近「@obs」;

回答

7

問題是values確實真的想要一個散列來操作。這是因爲它很特別:它清除了each所使用的佔位符。它需要一個實際的對象來清除它。

您可以在這裏以兩種方式之一。首先,如果你不喜歡裁判/ DEREF,你可以只拉臨時散出來的一個班輪的創建(請拿起比%h一個更好的名字爲您的實際代碼):

my %h = map { $_->{id} => $_->{value} } @obs; 
say for values %h; 

如果你不想做%h流連,只是拖放到一個臨時塊:

...code code code... 
{ 
    my %h = map { $_->{id} => $_->{value} } @obs; 
    say for values %h; 
} 
...code code code... 

另一種方法可能是效仿你的臨時散創建和values做:

my %seen; 
for (reverse @obs) { say $_->{value} unless $seen{$_->{id}}++ } 

真正重要的是你將如何處理這些數據。如果你只需要一次倒置散列的值,那麼你的單線可能是最好的解決方案。如果您稍後需要此數據(編號爲&值),則創建實際散列並使用它 - 不要多次執行此轉換,以便您可以將它們保留爲單行散列。

沒有進一步的背景知識,很難就採取哪種方法提供建議。

+1

我相信大衛金正在努力使'value','each','keys'等東西在引用上工作。它在5.13(dev版本)中,應該在5.14版本(生產版本)中。 – mpeters 2011-04-06 16:07:46

+0

@mpeters由於操作符重載的含糊性,有一些爭論,所以有些特徵可能在5.14中標記爲經驗。 – ikegami 2011-04-07 06:26:36

0

如果values在列表上工作,它將佔用該列表的每個第二個元素。所以

say for values %{{ map { $_->{id} => $_->{value} } @obs }}; 

say for every_odd map { $_->{id} => $_->{value} } @obs; 

現在,它完全有可能寫出這樣的功能,但它根本不是在這種情況下需要。我們可以簡單地做

say for map { $_->{value} } @obs; 

這簡化了

say $_->{value} for @obs; 

一個陷阱:如果不使用哈希,你不消除重複。

相關問題