有没有办法得到一个子哈希值?我需要使用哈希切片吗?举例来说:
%hash = ( a => 1, b => 2, c => 3 );
字符串我只想要
%hash = ( a => 1, b => 2 );
型
dy1byipe1#
散列切片返回与键列表相关的值。要获得散列切片,请将sigil更改为@并提供键列表(在本例中为"a"和"b"):
"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,你可以在一个步骤中获得键和值:
use v5.20; my %new_hash = %hash{qw/a b/};
kjthegm62#
你可能想要组装一个你想要的键的列表:
my @keys = qw(a b);
字符串然后使用一个循环来生成哈希:
my %hash_slice; for(@keys) { $hash_slice{$_} = %hash{$_}; }
型或者:
my %hash_slice = map { $_ => $hash{$_} } @keys;
型(My第二个是偏好,但你喜欢的是最好的。
sigwle7e3#
另一种方式:
my @keys = qw(a b); my %hash = (a => 1, b => 2, c => 3); my %hash_copy; @hash_copy{@keys} = @hash{@keys};
字符串
cvxl0en24#
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,但没有其他内容)。
$c->authenticate
nnsrf1az5#
perl 5.20中的新功能是hash slice通过使用%来返回键和值,就像这里最后一行那样:
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!
emeijp436#
太多的函数式编程让我首先想到了zip。安装了List::MoreUtils后,
zip
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解决方案带来的额外复制。(是的,在迭代时改变哈希值是安全的......只要改变只删除最近迭代的对。)
map
eoigrqb67#
散列是一个无序的容器,但是切片这个术语只有在有序容器中才有意义。也许可以考虑使用数组。否则,你可能只需要删除所有你不想产生“子散列”的元素。
7条答案
按热度按时间dy1byipe1#
散列切片返回与键列表相关的值。要获得散列切片,请将sigil更改为@并提供键列表(在本例中为
"a"
和"b"
):字符串
通常,您可以使用引号操作符来生成列表:
型
你也可以赋值给一个散列片,所以如果你想要一个包含另一个散列子集的新散列,你可以说
型
很多人会使用map来代替哈希切片:
型
从Perl 5.20.0开始,如果你使用% sigil而不是@ sigil,你可以在一个步骤中获得键和值:
型
kjthegm62#
你可能想要组装一个你想要的键的列表:
字符串
然后使用一个循环来生成哈希:
型
或者:
型
(My第二个是偏好,但你喜欢的是最好的。
sigwle7e3#
另一种方式:
字符串
cvxl0en24#
FWIW,我在这里使用Moose::Autobox:
字符串
在真实的生活中,我使用它从表单提交中提取“用户名”和“密码”,并将其传递给Catalyst的
$c->authenticate
(在我的情况下,它需要一个包含用户名和密码的hashref,但没有其他内容)。nnsrf1az5#
perl 5.20中的新功能是hash slice通过使用%来返回键和值,就像这里最后一行那样:
字符串
emeijp436#
太多的函数式编程让我首先想到了
zip
。安装了List::MoreUtils后,
字符串
不幸的是,List::MoreUtils的
zip
的原型抑制了型
如果你真的想避免中间变量,你可以
型
或者只是编写自己的
zip
,而不使用有问题的原型(这根本不需要List::MoreUtils)。型
如果你要在原地变异,
型
避免了
map
和zip
解决方案带来的额外复制。(是的,在迭代时改变哈希值是安全的......只要改变只删除最近迭代的对。)eoigrqb67#
散列是一个无序的容器,但是切片这个术语只有在有序容器中才有意义。也许可以考虑使用数组。否则,你可能只需要删除所有你不想产生“子散列”的元素。