问题:有可能在每个hashrefs组数组引用与等于间隔值。在每个这样的组中,需要标识具有最低能量值 的hashref以替换该组。
的大部分工作是在partition_equal()
完成,标识与相等间隔
use warnings;
use strict;
use List::Util qw(reduce);
use Data::Dump qq(dd);
# Test data: two groups of equal-spacer hashrefs, in the first array only
my %hash = (
kA => [
{ 'energy' => -4.3, 'spacer' => 'AGGCACC' },
{ 'energy' => -2.3, 'spacer' => 'AGGCACC' },
{ 'energy' => -3.3, 'spacer' => 'CAGT' },
{ 'energy' => -1.5, 'spacer' => 'GTT' },
{ 'energy' => -2.5, 'spacer' => 'GTT' },
],
kB => [
{ 'energy' => -4.4, 'spacer' => 'CAGT' },
{ 'energy' => -4.1, 'spacer' => 'GTT' },
{ 'energy' => -4.1, 'spacer' => 'TTG' },
],
);
#dd \%hash;
for my $key (keys %hash) {
my ($spv, $unique) = partition_equal($hash{$key});
next if not $spv;
# Extract minimum-energy hashref from each group and add to arrayref
# $unique, so that it can eventually overwrite this key's arrayref
foreach my $spacer (keys %$spv) {
my $hr_min = reduce {
$a->{energy} < $b->{energy} ? $a : $b
} @{$spv->{$spacer}};
push @$unique, $hr_min;
}
# new: unique + lowest-energy ones for each equal-spacer group
$hash{$key} = $unique if keys %$spv;
}
dd \%hash;
# Sort array and compare neighbouring elements (hashrefs)
sub partition_equal {
my $ra = shift;
my @sr = sort { $a->{spacer} cmp $b->{spacer} } @$ra;
# %spv: spacer value => [ hashrefs with it ], ...
# @unique: hasrefs with unique spacer values
my (%spv, @unique);
# Process first and last separately, to not have to test for them
($sr[0]{spacer} eq $sr[1]{spacer})
? push @{$spv{$sr[0]{spacer}}}, $sr[0]
: push @unique, $sr[0];
for my $i (1..$#sr-1) {
if ($sr[$i]{spacer} eq $sr[$i-1]{spacer} or
$sr[$i]{spacer} eq $sr[$i+1]{spacer})
{
push @{$spv{$sr[$i]{spacer}}}, $sr[$i]
}
else { push @unique, $sr[$i] }
}
($sr[-1]{spacer} eq $sr[-2]{spacer})
? push @{$spv{$sr[-1]{spacer}}}, $sr[-1]
: push @unique, $sr[-1];
return if not keys %spv;
return \%spv, \@unique;
}
输出
kA => [
{ energy => -3.3, spacer => "CAGT" },
{ energy => -2.5, spacer => "GTT" },
{ energy => -4.3, spacer => "AGGCACC" },
],
kB => [
{ energy => -4.4, spacer => "CAGT" },
{ energy => -4.1, spacer => "GTT" },
{ energy => -4.1, spacer => "TTG" },
],
内部arrayrefs的次序并不维持hashref基;新的arrayref具有唯一间隔值的第一个hashrefs,然后是具有最低能量值的那些(对于具有相同间隔值的每个原始组)。
子排序通过间隔值输入,以便它可以通过简单地遍历排序后的数组并仅比较邻居来识别相等的数据。这应该是合理有效的。
未来,请求使用'Dumper(\%hash)'而不是'Dumper(%hash)' – ikegami
“*我想比较$ VAR125/$中的间隔哈希值VAR126哈希与对方*“是什么意思?哈希没有“有价值”,你想要什么结果? – ikegami
例如我想比较一下垫片:** CAGT **,** GTT **和** TTG **,看看它们是否相同。然后像我这样应用一些if语句。 –