合并 Perl Hashrefs 和 unique
Merge Perl Hashrefs and unique
我有两个具有以下内容的 perl 散列:
第一个:
$VAR1 = {
'name1' => [
'adam',
'bob'
],
'name2' => [
'Miller',
'Schumacher'
]
};
第二个:
$VAR1 = {
'name1' => [
'tina',
'jason',
'jeff'
],
'name2' => [
'Miller',
'Schumacher',
'Schmidt'
]
};
如何合并它们以获得以下结构并在 name2 中获得唯一项?
$VAR1 = {
'name1' => [
'tina',
'jason',
'jeff',
'adam',
'bob',
],
'name2' => [
'Miller',
'Schumacher',
'Schmidt'
]
};
您必须遍历 name1, name2
个键并从 $VAR2->{$k}
和 $VAR1->{$k}
数组中过滤重复项,
use strict;
use warnings;
my $VAR1 = {
'name1' => [ 'adam', 'bob' ],
'name2' => [ 'Miller', 'Schumacher' ]
};
my $VAR2 = {
'name1' => [ 'tina', 'jason', 'jeff' ],
'name2' => [ 'Miller', 'Schumacher', 'Schmidt' ]
};
my %result;
for my $k (keys %$VAR1) {
my %seen;
$result{$k} = [
grep { !$seen{$_}++ } @{ $VAR2->{$k} }, @{ $VAR1->{$k} }
];
}
use Data::Dumper;
print Dumper \%result;
输出
$VAR1 = {
'name2' => [
'Miller',
'Schumacher',
'Schmidt'
],
'name1' => [
'tina',
'jason',
'jeff',
'adam',
'bob'
]
};
如果您的需求非常具体——用键 name1
和 name2
合并两个散列,那么下面应该可以解决问题:
my $first = {
name1 => [ qw(adam bob) ],
name2 => [ qw(Miller Schumacher) ],
};
my $second = {
name1 => [ qw(tina jason jeff) ],
name2 => [ qw(Miller Schumacher Schmidt) ],
};
my $merged = {
name1 => [ values %{$first->{name1}}, values %{$second->{name1}} ],
name2 => [ values %{$first->{name2}}, values %{$second->{name2}} ],
};
如果密钥不固定且事先已知,Сухой27 的答案将有效,至少在结构只有两层深的情况下。
如果它可以更深入,你将需要一个递归解决方案。
这是一个通用的解决方案,可以采用任意数量的散列,并处理任何散列中丢失的键
它遍历所有要组合的散列键的列表,并使用 map
将所有散列中每个键的数组值连接起来
我使用Data::Dump
只是为了显示结果哈希数据
use strict;
use warnings;
use List::MoreUtils qw/ uniq /;
use Data::Dump;
my %ha = (
name1 => [ "adam", "bob" ],
name2 => [ "Miller", "Schumacher" ],
);
my %hb = (
name1 => [ "tina", "jason", "jeff" ],
name2 => [ "Miller", "Schumacher", "Schmidt" ],
);
my @hashes = \( %ha, %hb );
my %new;
for my $k ( uniq map keys %$_, @hashes ) {
$new{$k} = [
uniq map @{ $_->{$k} // [] }, @hashes
];
}
dd \%new;
输出
{
name1 => ["adam", "bob", "tina", "jason", "jeff"],
name2 => ["Miller", "Schumacher", "Schmidt"],
}
如果出于任何原因您不想安装非核心库模块List::MoreUtils
,那么您可以使用此版本的uniq
函数
sub uniq {
my %seen;
grep { not $seen{$_}++ } @_;
}
Hash::Merge 自定义模块的右先例行为以在合并数组时统一元素。
use strict;
use Hash::Merge qw/merge :custom/;
use List::MoreUtils qw/uniq/;
use Data::Dumper;
my $href1 = { name1 => [ qw/adam bob/ ],
name2 => [ qw/Miller Schumacher/ ] };
my $href2 = { name1 => [ qw/tina jason jeff/ ],
name2 => [ qw/Miller Schumacher Schmidt/ ] };
Hash::Merge::specify_behavior( {
SCALAR => {
SCALAR => sub { $_[1] },
ARRAY => sub { [ $_[0], @{$_[1]} ] },
HASH => sub { $_[1] },
},
ARRAY => {
SCALAR => sub { $_[1] },
# This returns unique elements from two arrays passed
ARRAY => sub { [ uniq( @{$_[0]}, @{$_[1]}) ] },
HASH => sub { $_[1] },
},
HASH => {
SCALAR => sub { $_[1] },
ARRAY => sub { [ values %{$_[0]}, @{$_[1]} ] },
HASH => sub { Hash::Merge::_merge_hashes( $_[0], $_[1] ) },
},
},
'Right precedent + Uniq array',
);
my $href3 = merge($href1, $href2);
print Dumper $href3;
产生输出:
$VAR1 = {
'name2' => [
'Miller',
'Schumacher',
'Schmidt'
],
'name1' => [
'adam',
'bob',
'tina',
'jason',
'jeff'
]
};
我有两个具有以下内容的 perl 散列:
第一个:
$VAR1 = {
'name1' => [
'adam',
'bob'
],
'name2' => [
'Miller',
'Schumacher'
]
};
第二个:
$VAR1 = {
'name1' => [
'tina',
'jason',
'jeff'
],
'name2' => [
'Miller',
'Schumacher',
'Schmidt'
]
};
如何合并它们以获得以下结构并在 name2 中获得唯一项?
$VAR1 = {
'name1' => [
'tina',
'jason',
'jeff',
'adam',
'bob',
],
'name2' => [
'Miller',
'Schumacher',
'Schmidt'
]
};
您必须遍历 name1, name2
个键并从 $VAR2->{$k}
和 $VAR1->{$k}
数组中过滤重复项,
use strict;
use warnings;
my $VAR1 = {
'name1' => [ 'adam', 'bob' ],
'name2' => [ 'Miller', 'Schumacher' ]
};
my $VAR2 = {
'name1' => [ 'tina', 'jason', 'jeff' ],
'name2' => [ 'Miller', 'Schumacher', 'Schmidt' ]
};
my %result;
for my $k (keys %$VAR1) {
my %seen;
$result{$k} = [
grep { !$seen{$_}++ } @{ $VAR2->{$k} }, @{ $VAR1->{$k} }
];
}
use Data::Dumper;
print Dumper \%result;
输出
$VAR1 = {
'name2' => [
'Miller',
'Schumacher',
'Schmidt'
],
'name1' => [
'tina',
'jason',
'jeff',
'adam',
'bob'
]
};
如果您的需求非常具体——用键 name1
和 name2
合并两个散列,那么下面应该可以解决问题:
my $first = {
name1 => [ qw(adam bob) ],
name2 => [ qw(Miller Schumacher) ],
};
my $second = {
name1 => [ qw(tina jason jeff) ],
name2 => [ qw(Miller Schumacher Schmidt) ],
};
my $merged = {
name1 => [ values %{$first->{name1}}, values %{$second->{name1}} ],
name2 => [ values %{$first->{name2}}, values %{$second->{name2}} ],
};
如果密钥不固定且事先已知,Сухой27 的答案将有效,至少在结构只有两层深的情况下。 如果它可以更深入,你将需要一个递归解决方案。
这是一个通用的解决方案,可以采用任意数量的散列,并处理任何散列中丢失的键
它遍历所有要组合的散列键的列表,并使用 map
我使用Data::Dump
只是为了显示结果哈希数据
use strict;
use warnings;
use List::MoreUtils qw/ uniq /;
use Data::Dump;
my %ha = (
name1 => [ "adam", "bob" ],
name2 => [ "Miller", "Schumacher" ],
);
my %hb = (
name1 => [ "tina", "jason", "jeff" ],
name2 => [ "Miller", "Schumacher", "Schmidt" ],
);
my @hashes = \( %ha, %hb );
my %new;
for my $k ( uniq map keys %$_, @hashes ) {
$new{$k} = [
uniq map @{ $_->{$k} // [] }, @hashes
];
}
dd \%new;
输出
{
name1 => ["adam", "bob", "tina", "jason", "jeff"],
name2 => ["Miller", "Schumacher", "Schmidt"],
}
如果出于任何原因您不想安装非核心库模块List::MoreUtils
,那么您可以使用此版本的uniq
函数
sub uniq {
my %seen;
grep { not $seen{$_}++ } @_;
}
Hash::Merge 自定义模块的右先例行为以在合并数组时统一元素。
use strict;
use Hash::Merge qw/merge :custom/;
use List::MoreUtils qw/uniq/;
use Data::Dumper;
my $href1 = { name1 => [ qw/adam bob/ ],
name2 => [ qw/Miller Schumacher/ ] };
my $href2 = { name1 => [ qw/tina jason jeff/ ],
name2 => [ qw/Miller Schumacher Schmidt/ ] };
Hash::Merge::specify_behavior( {
SCALAR => {
SCALAR => sub { $_[1] },
ARRAY => sub { [ $_[0], @{$_[1]} ] },
HASH => sub { $_[1] },
},
ARRAY => {
SCALAR => sub { $_[1] },
# This returns unique elements from two arrays passed
ARRAY => sub { [ uniq( @{$_[0]}, @{$_[1]}) ] },
HASH => sub { $_[1] },
},
HASH => {
SCALAR => sub { $_[1] },
ARRAY => sub { [ values %{$_[0]}, @{$_[1]} ] },
HASH => sub { Hash::Merge::_merge_hashes( $_[0], $_[1] ) },
},
},
'Right precedent + Uniq array',
);
my $href3 = merge($href1, $href2);
print Dumper $href3;
产生输出:
$VAR1 = {
'name2' => [
'Miller',
'Schumacher',
'Schmidt'
],
'name1' => [
'adam',
'bob',
'tina',
'jason',
'jeff'
]
};