如何在Perl中获得散列的唯一部分?
有没有办法获得子哈希?我需要使用散列片吗?如何在Perl中获得散列的唯一部分?
例如:
%hash = (a => 1, b => 2, c => 3);
我只想
%hash = (a => 1, b => 2);
Hash slices返回与键列表关联的值。为了让你改变印记为@散片,并提供键的列表(在这种情况下"a"
和"b"
):
my @items = @hash{"a", "b"};
通常你可以使用一个引用字操作产生的列表:
my @items = @hash{qw/a b/};
还可以分配到一个哈希片,所以如果你想要包含其他散子集的新的哈希,你可以说
my %new_hash;
@new_hash{qw/a b/} = @hash{qw/a b/};
很多人会用一个map,而不是散片:
my %new_hash = map { $_ => $hash{$_} } qw/a b/;
用Perl 5.20.0开始,你可以得到键和值在一个步骤,如果你使用的印记%,而不是@印记:
my %new_hash = %hash{qw/a b/};
这使得为什么“地图”工作w /哈希清晰一点给我。谢谢 – 2009-06-11 04:15:11
拉里沃尔,布莱恩福伊和查斯。欧文斯......谢谢你这个非常全面的解释! – bernie 2009-06-11 04:19:20
散列是一个无序的容器,但片这一术语才真正有意义有序容器方面。也许看看使用数组。否则,你可能只需要删除你不想产生你的'子哈希'的所有元素。
在Perl中,散列片很有用,并且完全支持。要了解更多重新阅读 [_perldata_中的'切片'部分](http://perldoc.perl.org/perldata.html#Slices)。 – 2015-11-19 13:36:50
你可能想组装你想要的密钥列表:
my @keys = qw(a b);
然后使用一个循环,使哈希:
my %hash_slice;
for(@keys) {
$hash_slice{$_} = %hash{$_};
}
或者:
my %hash_slice = map { $_ => $hash{$_} } @keys;
(我的偏好是第二个,但你喜欢哪一个最好。)
过多的函数式编程让我首先想到zip
。
在安装List::MoreUtils,
use List::MoreUtils qw(zip);
%hash = qw(a 1 b 2 c 3);
@keys = qw(a b);
@values = @hash{@keys};
%hash = zip @keys, @values;
不幸的是,名单的原型:: MoreUtils的zip
抑制
zip @keys, @hash{@keys};
如果你真的想避免中间变量,你可以
zip @keys, @{[@hash{@keys}]};
或者只写你自己的zip
没有问题的原型。 (这根本不需要List :: MoreUtils。)
sub zip {
my $max = -1;
$max < $#$_and $max = $#$_ for @_;
map { my $ix = $_; map $_->[$ix], @_; } 0..$max;
}
%hash = zip \@keys, [@hash{@keys}];
如果你要就地进行变异,
%hash = qw(a 1 b 2 c 3);
%keep = map +($_ => 1), qw(a b);
$keep{$a} or delete $hash{$a} while ($a, $b) = each %hash;
避免额外复制的map
和zip
解决方案承担。 (是的,变异的散列当你迭代它是安全的......只要突变只删除最近反复对)
FWIW,我用麋:: Autobox这里:
my $hash = { a => 1, b => 2, c => 3, d => 4 };
$hash->hslice([qw/a b/]) # { a => 1, b => 2 };
在现实生活中,我使用它从表单提交中提取“用户名”和“密码”,并将其传递给Catalyst的$c->authenticate
(在我的情况下,期望的是包含用户名和密码的hashref,但没有其他)。
还有一种方法:
my @keys = qw(a b);
my %hash = (a => 1, b => 2, c => 3);
my %hash_copy;
@hash_copy{@keys} = @hash{@keys};
新在Perl 5.20是散片用%喜欢在最后一行这里返回键以及价值观:
my %population = ('Norway',5000000,'Sweden',9600000,'Denmark',5500000);
my @slice_values = @population{'Norway','Sweden'}; # all perls can do this
my %slice_hash = %population{'Norway','Sweden'}; # perl >= 5.20 can do this!
由于没有什么逻辑上“片”我怀疑与'地图'有关。 在一个数组中,你会根据索引来做它,但是在哈希中没有可靠的内部数据表示。你需要一些类型的限定符(正则表达式?)来定义应该进入subhash的内容以及不应该进入的内容。 – 2009-06-11 03:59:53
顺便说一句,你的哈希语法是错误的:使用圆括号“()”为一个普通的散列,“{}”为匿名散列引用。 – trendels 2009-06-11 07:35:49