有没有办法获得子哈希?我需要使用哈希切片吗?
例如:
%hash = ( a => 1, b => 2, c => 3 );
我只想要
%hash = ( a => 1, b => 2 );
答案 0 :(得分:51)
Hash slices返回与键列表关联的值。要获取哈希切片,请将sigil更改为@并提供密钥列表(在本例中为"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开始,如果使用%sigil而不是@sigil,则可以一步获取键和值:
my %new_hash = %hash{qw/a b/};
答案 1 :(得分:9)
您可能想要组合所需的键列表:
my @keys = qw(a b);
然后使用循环来制作哈希:
my %hash_slice;
for(@keys) {
$hash_slice{$_} = %hash{$_};
}
或者:
my %hash_slice = map { $_ => $hash{$_} } @keys;
(我的偏好是第二个,但无论你喜欢哪个最好。)
答案 2 :(得分:6)
另一种方式:
my @keys = qw(a b);
my %hash = (a => 1, b => 2, c => 3);
my %hash_copy;
@hash_copy{@keys} = @hash{@keys};
答案 3 :(得分:3)
太多的函数式编程使我首先想到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;
不幸的是,List :: 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
解决方案产生的额外复制。 (是的,在迭代它时改变哈希是安全的......只要突变只删除最近迭代的对。)
答案 4 :(得分:3)
FWIW,我在这里使用Moose :: Autobox:
my $hash = { a => 1, b => 2, c => 3, d => 4 };
$hash->hslice([qw/a b/]) # { a => 1, b => 2 };
在现实生活中,我使用它从表单提交中提取“用户名”和“密码”,并将其传递给Catalyst的$c->authenticate
(在我的情况下,它需要包含用户名和密码的hashref,但没有别的。)
答案 5 :(得分:2)
perl 5.20中的新功能是散列片返回键以及值,在最后一行使用%like:
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!
答案 6 :(得分:-3)
散列是一个无序容器,但术语切片只对有序容器有意义。也许考虑使用数组。否则,您可能只需要删除所有不想产生“子哈希”的元素。