Arrays 在两个HoA中查找重叠值
我有两个HOA,每个HOA包含两个数组作为值。下面的代码首先按键对第一个HoA进行排序,如果键相同,则按第一个数组的对应值排序:Arrays 在两个HoA中查找重叠值,arrays,perl,hash,multidimensional-array,Arrays,Perl,Hash,Multidimensional Array,我有两个HOA,每个HOA包含两个数组作为值。下面的代码首先按键对第一个HoA进行排序,如果键相同,则按第一个数组的对应值排序: #!/usr/bin/perl use warnings; use strict; use Data::Dumper; $Data::Dumper::Sortkeys = 1; my @array1 = qw (1 1 1 4 5); # Note '1' appears several times my @array2 = qw (10 45 2 1 6); my
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
my @array1 = qw (1 1 1 4 5); # Note '1' appears several times
my @array2 = qw (10 45 2 1 6);
my @array3 = qw (a b c d e);
my %hash1;
push @{$hash1{$array1[$_]}}, [ $array2[$_], $array3[$_] ] for 0 .. $#array1;
my @arrayA = qw (2 5 1 0 4);
my @arrayB = qw (1 3 6 0 7);
my @arrayC = qw (a z v i d);
my %hash2;
push @{$hash2{$arrayA[$_]}}, [ $arrayB[$_], $arrayC[$_]] for 0 .. $#arrayA;
for my $key (sort keys %hash1) {
for my $value (sort { $a->[0] <=> $b->[0] } @{ $hash1{$key} } ) {
my ($arr2, $arr3) = @$value;
print "$key: $arr2\t$arr3\n";
}
}
哈希2
期望输出:
(已删除包含array3和arrayC的匹配元素的行)
i、 e.删除:
1: 10 a
4: 1 d
从第一个散列开始,然后:
2: 1 a
4: 7 d
从第二
如果我比较键,我会使用:
for my $key (sort keys %hash1) {
if (exists $hash1{$key}) {
next;
}
}
foreach (@array3) {
if ($_~~ @arrayC) {
next;
}
}
如果我比较两个阵列,我会使用:
for my $key (sort keys %hash1) {
if (exists $hash1{$key}) {
next;
}
}
foreach (@array3) {
if ($_~~ @arrayC) {
next;
}
}
如何对HOA中的值实现相同的效果?因为您希望从两个哈希中对输出进行排序,我建议您合并它们。在这个过程中,还可以抛出没有唯一键的值 为了使其按预期工作,我们应该创建一组出现在两个哈希中的最后值项
use List::MoreUtils 'uniq';
# build a hash of all common values for the last col, i.e.
# uniq $hash->{*}[*][1], where `*` would be a slice
my %last_col;
for my $hash (\%hash1, \%hash2) {
$last_col{$_}++ for uniq map $_->[1], map @$_, values %$hash;
}
$last_col{$_} < 2 and delete $last_col{$_} for keys %last_col;
所有值现在都已合并,因此让我们将它们打印出来:
for my $key (sort { $a <=> $b } keys %merged) {
for my $value (sort {$a->[0] <=> $b->[0]} @{ $merged{$key} }) {
printf "%s: %s\n", $key, join "\t", @$value;
}
}
确切地说,这可以在没有显式合并的情况下完成,但这会使代码变得不必要的复杂。谢谢你的回答-我会尝试一下,并让你知道。从你的观点来看,我是用正确的数据结构来实现我想要达到的目的吗?@ Frut蛙是的,你的数据结构是正确的,尽管我会考虑将一些操作封装在类内。
my %merged;
for my $hash (\%hash1, \%hash2) {
for my $key (keys %$hash) {
push @{ $merged{$key} }, grep {not exists $last_col{$_->[1]} } @{ $hash->{$key} };
}
}
for my $key (sort { $a <=> $b } keys %merged) {
for my $value (sort {$a->[0] <=> $b->[0]} @{ $merged{$key} }) {
printf "%s: %s\n", $key, join "\t", @$value;
}
}
0: 0 i
1: 2 c
1: 6 v
1: 45 b
5: 3 z
5: 6 e