回答
這是你想要的嗎? (未經測試)
sub for_hash {
my ($hash, $fn) = @_;
while (my ($key, $value) = each %$hash) {
if ('HASH' eq ref $value) {
for_hash $value, $fn;
}
else {
$fn->($value);
}
}
}
my $example = {'key' => {'key2' => {'key3' => 'value'}}};
for_hash $example, sub {
my ($value) = @_;
# Do something with $value...
};
我喜歡你的Yoda條件在第四行:) – 2013-08-05 08:08:22
foreach my $keyname (keys(%foo) {
my $subhash = $foo{$keyname};
# stuff with $subhash as the value at $keyname
}
這應該是$ foo {$ keyname}而不是%foo {$ keyname}! – 2010-03-02 13:06:33
所以它應該。這就是我在咖啡之前發佈的內容。 – monksp 2010-03-02 13:12:15
你將不得不循環兩次。即
while (($family, $roles) = each %HoH) {
print "$family: ";
while (($role, $person) = each %$roles) {
print "$role=$person ";
}
print "\n";
}
另外,請通讀perldoc perldsc。你可以深入瞭解哈希值
This post可能是有用的。
foreach my $key (keys %hash) {
foreach my $key2 (keys %{ $hash{$key} }) {
foreach my $key3 (keys %{ $hash{$key}{$key2} }) {
$value = $hash{$key}{$key2}->{$key3};
# .
# .
# Do something with $value
# .
# .
# .
}
}
}
這個答案建立在Dave Hinton的背後 - 即寫一個通用子程序來散步散列結構。這樣的散列函數需要一個代碼引用,並簡單地爲散列中的每個葉節點調用該代碼。
使用這種方法,可以使用相同的散列函數來做很多事情,具體取決於我們給出的回調函數。爲了獲得更大的靈活性,您需要傳遞兩個回調函數 - 一個在值爲哈希引用時調用,另一個在普通標量值時調用。 Marc Jason Dominus的優秀書籍Higher Order Perl更深入地探討了這樣的策略。
use strict;
use warnings;
sub hash_walk {
my ($hash, $key_list, $callback) = @_;
while (my ($k, $v) = each %$hash) {
# Keep track of the hierarchy of keys, in case
# our callback needs it.
push @$key_list, $k;
if (ref($v) eq 'HASH') {
# Recurse.
hash_walk($v, $key_list, $callback);
}
else {
# Otherwise, invoke our callback, passing it
# the current key and value, along with the
# full parentage of that key.
$callback->($k, $v, $key_list);
}
pop @$key_list;
}
}
my %data = (
a => {
ab => 1,
ac => 2,
ad => {
ada => 3,
adb => 4,
adc => {
adca => 5,
adcb => 6,
},
},
},
b => 7,
c => {
ca => 8,
cb => {
cba => 9,
cbb => 10,
},
},
);
sub print_keys_and_value {
my ($k, $v, $key_list) = @_;
printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $v, "@$key_list";
}
hash_walk(\%data, [], \&print_keys_and_value);
這幫了我很多,謝謝 – 2010-03-03 13:39:33
較早的答案顯示如何推出自己的解決方案,這是很好的做至少一次,以便您瞭解如何perl的引用和數據結構工作的膽量。如果您尚未閱讀,您應該仔細閱讀perldoc perldsc和perldoc perlref。
但是,您不需要編寫自己的解決方案 - CPAN上已經有一個模塊,它將通過任意複雜的數據結構迭代:Data::Visitor。
+1謝謝,'Data :: Visitor'看起來很有用。從文檔看,如何做一些簡單的事情並不是很明顯 - 例如,遍歷嵌套的散列結構,打印葉節點值和它們的鍵(直接和他們的祖先)。我相信這是可行的。只需要將我的頭包裹一下就可以了。 :) – FMc 2010-03-02 20:05:18
這不是一個真正的新答案,但我想分享如何做超過 只是遞歸地打印所有的散列值,但如果需要也可以修改它們。
這是我在 值傳遞給回調作爲參考,所以我的回調 程序可以再修改中的散列值每的dave4420的答案曾經如此輕微的修改。
我也不得不重建散列,因爲每個循環創建副本 沒有引用。
sub hash_walk {
my $self = shift;
my ($hash, $key_list, $callback) = @_;
while (my ($k, $v) = each %$hash) {
# Keep track of the hierarchy of keys, in case
# our callback needs it.
push @$key_list, $k;
if (ref($v) eq 'HASH') {
# Recurse.
$self->hash_walk($v, $key_list, $callback);
}
else {
# Otherwise, invoke our callback, passing it
# the current key and value, along with the
# full parentage of that key.
$callback->($k, \$v, $key_list);
}
pop @$key_list;
# Replace old hash values with the new ones
$hash->{$k} = $v;
}
}
hash_walk(\%prj, [], \&replace_all_val_strings);
sub replace_all_val_strings {
my ($k, $v, $key_list) = @_;
printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $$v, "@$key_list";
$$v =~ s/oldstr/newstr/;
printf "k = %-8s v = %-4s key_list = [%s]\n", $k, $$v, "@$key_list";
}
如果您正在使用Perl作爲一個 「CPAN解釋」 那麼除了Data::Visitor
和有超級簡單Data::Traverse
:
use Data::Traverse qw(traverse);
my %test_hash = (
q => [qw/1 2 3 4/],
w => [qw/4 6 5 7/],
e => ["8"],
r => {
r => "9" ,
t => "10" ,
y => "11" ,
} ,
);
traverse { next if /ARRAY/; print "$a => $b\n" if /HASH/ && $b > 8 } \%test_hash;
輸出:
t => 10
y => 11
$a
和$b
被視爲特殊變量在這裏(和sort()
一樣),而在traverse()
函數中。 Data::Traverse
是一個非常簡單但非常有用的模塊,沒有非CORE依賴關係。
- 1. 如何在perl中使用hash和getopts
- 2. 在Perl中包含Hashes內的哈希
- 3. 如何迭代Perl PDL piddle?
- 4. 遍歷Perl Hashes數組
- 5. Perl hash Data :: Dumper
- 6. 迭代通過在Perl
- 7. 如何迭代Perl數組引用?
- 8. 如何迭代這個Perl結構?
- 9. 如何用Perl處理hash-ref?
- 10. Perl hash Data :: Dumper output
- 11. Decode Hash :: MultiValue in perl
- 12. Array to a hash perl
- 13. 在perl中迭代IP地址範圍
- 14. 在perl中迭代哈希值
- 15. 什麼@ {hash {$ key}}在Perl中的含義?
- 16. 在Perl中,我如何迭代數組的多個元素?
- 17. 如何在Perl中同時迭代多個列表?
- 18. 如何在[perl]中將散列[hashes] *的散列值作爲CSV打印
- 19. 如何獲得no的數量。密鑰在perl 6%HASH中?
- 20. 如何在Perl中嵌入Perl代碼?
- 21. 如何在Ruby中迭代?
- 22. 如何在Ruby中迭代?
- 23. 如何在MySQL中迭代?
- 24. Perl Perl選擇屬性迭代
- 25. Perl:在Perl-Hash中存儲來自Mysql-table的列
- 26. Perl hash到json轉換?
- 27. 幫助理解perl hash
- 28. Perl HTTP ::請求HASH錯誤?
- 29. 在Hash Ruby 1.8.7上維護迭代次序?
- 30. 在hash參數上迭代調用self.send來初始化()
你可以舉一個更現實的例子。你在哪裏遇到這樣的結構?它是幹什麼用的?您想做什麼? 也許另一個數據結構會更適合這項任務? – Aurril 2010-03-02 13:04:19
@Aurril:嵌套散列結構對許多事情都很有用,請參閱下面我的帖子中的鏈接。 – Zaid 2010-03-02 13:13:24
每個散列都有多個鍵嗎? – Svante 2010-03-02 13:22:32