問題:有可能在每個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語句。 –