我正在编写一段接收参数%args
且配置为%conf
的代码。我需要将某些值从这两个哈希传递到另一个Perl模块,而其他值仅与我自己的代码相关。
如何以优雅的方式合并两个(或多个)哈希切片或合并哈希,同时仅保留选定的密钥?
重点:
%args
的值将覆盖%conf
。%args
中未包含的密钥和%conf
中未包含的密钥不得包含在%result
中。示例输入:
my %conf = (
path => '/usr/local/bin/',
size => 42,
other => 'value', # isn't used
);
my %args = (
path => '~/bin/', # overrides $conf{path}
foo => 'bar',
);
my @keys = qw<path size foo bar>; # 'bar' isn't contained in either hash!
预期结果:
my %result = (
path => '~/bin/', # from $args{patħ}
size => 42,
foo => 'bar',
);
对于简单的合并,这就足够了:
my %result = ( %conf, %args );
简单的哈希切片也很简单:
my %slice = map { $_ => $hash{$_} } qw<foo bar baz>;
缩减到现有密钥已经需要一个临时变量:
my %keys = map { $_ => 1 } qw<foo bar baz>;
grep { $keys{$_} } %hash;
但总而言之,变得非常复杂:
my @keys = qw<foo bar baz>;
my %keys = map { $_ => 1 } @keys;
my %result = (
map( { $_ => $conf{$_} } grep { $keys{$_} } keys %conf ),
map( { $_ => $args{$_} } grep { $keys{$_} } keys %args ),
);
有没有更好的方法来编码?
答案 0 :(得分:1)
这是对您修改过的问题的回复。我尽最大努力写一些干净的东西只删除不在@keys
中的组合哈希的任何元素,使用中间%wanted
哈希来描述在数组中出现哪些哈希键
use strict;
use warnings 'all';
# Set up test data
my %conf = (
path => '/usr/local/bin/',
size => 42,
other => 'value', # isn't used
);
my %args = (
path => '~/bin/', # overrides $conf{path}
foo => 'bar',
);
my @keys = qw/ path size foo bar /; # 'bar' isn't contained in either hash!
# Combine and select
my %wanted = map { $_ => 1 } @keys;
my %result = (%conf, %args);
delete @result{ grep { not $wanted{$_} } keys %result };
# Display the result
use Data::Dump;
dd \%result;
{ foo => "bar", path => "~/bin/", size => 42 }
这似乎符合法案。我已经从您的帖子中复制了测试数据
将两个哈希值合并到%join
,%args
覆盖%conf
,将其放在列表分配中第二位
然后使用切片从%result
%join
我只使用Data::Dump来显示上述代码的结果
请注意,如果@keys
中的字符串未出现在 哈希中,则它将包含在%results
中且值为undef
“所需密钥列表可用作列表或保存在数组中。”
这是一个非常模糊的要求。要使此解决方案起作用,您需要一组键,因此只需将列表存储为数组
use strict;
use warnings 'all';
# Set up test data
my %conf = (
path => '/usr/local/bin/',
size => 42,
other => 'value', # isn't used
);
my %args = (
path => '~/bin/', # overrides $conf{path}
foo => 'bar',
);
my @keys = qw/ path size foo /;
# Combine and select
my %join = (%conf, %args);
my %result;
@result{@keys} = @join{@keys};
# Display the result
use Data::Dump;
dd \%result;
{ foo => "bar", path => "~/bin/", size => 42 }