我有两个HoA,每个都包含2个数组作为值。下面的代码首先通过它的键对第一个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 @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";
}
}
我希望能够执行上述功能,但还要比较它们之间的值(例如@ array3和@arrayC。如果两个数组中都存在一个值,那么我想跳过它,并为每个数据打印出键和值对该阵列“行”是唯一的。
hash1和hash2的输出(原样),用*
表示的值重叠:
HASH1
1: 2 c
1: 10 a *
1: 45 b
4: 1 d *
5: 6 e
HASH2
0: 0 i
1: 6 v
2: 1 a *
4: 7 d *
5: 3 z
期望的输出: (删除了包含array3和arrayC匹配元素的行)
0: 0 i
1: 2 c
1: 6 v
1: 45 b
5: 3 z
5: 6 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;
}
}
如何在HoAs中实现相同的值?
答案 0 :(得分:1)
因为你想要从两个哈希中排序输出,我建议你合并它们。在该过程中,您还可以抛弃没有唯一键的值。
为了使其按预期工作,我们应该创建一组在两个哈希中出现的最后一个值项。
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;
我们在那里所做的相当于最后一列值的交集。 现在我们可以合并两个哈希值,当最后一个col存在于两者中时跳过。
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
确切地说,可以在没有明确合并的情况下被拉出,但这会使代码变得复杂。