Как получить доступ к вложенному хэшу массивов в цикле?
У меня есть данные в этом формате
a1 1901 4
a1 1902 5
a3 1902 6
a4 1902 7
a4 1903 8
a5 1903 9
Я хочу рассчитать совокупный балл (3-й столбец) для каждого объекта в первом столбце. Поэтому я попытался создать хеш, и мой код выглядит так:
use strict;
use warnings;
use Data::Dumper;
my $file = shift;
open (DATA, $file);
my %hash;
while ( my $line = <DATA> ) {
chomp $line;
my ($protein, $year, $score) = split /\s+/, $line;
push @{ $hash{$protein}{$year} }, $score;
}
print Dumper \%hash;
close DATA:
Вывод выглядит так
$VAR1 = {
'a3' => {
'1902' => [
5
]
},
'a1' => {
'1902' => [
6
],
'1901' => [
4
]
},
'a4' => {
'1903' => [
8
],
'1902' => [
7
]
},
'a5' => {
'1903' => [
9
]
}
};
Теперь я хочу получить доступ к каждой сущности в столбце 1 (a1,a2,a3) и добавить оценку, поэтому желаемый результат будет примерно таким:
a1 1901 4
a1 1902 9 # 4+5
a3 1902 6
a4 1902 7
a4 1903 16 # 7+9
a5 1903 9
Но я не могу придумать, как получить доступ к значениям созданного хеша в цикле, чтобы добавить значения?
2 ответа
Решение
Если данные всегда сортируются в том виде, в котором вы их отображаете, вы можете обрабатывать данные, считывая их из файла:
while ( <DATA> ) {
my ($protein, $year, $score) = split;
$total = 0 unless $protein eq $current;
$total += $score;
print "$protein $year $total\n";
$current = $protein;
}
выход
a1 1901 4
a1 1902 9
a3 1902 6
a4 1902 7
a4 1903 15
a5 1903 9
Я думаю
a4 1903 16 # Sum of a4 1902 and a5 1903
должно быть
a4 1903 15 # Sum of a4 1902 and a4 1903
Если так,
my %scores_by_protein_and_year;
while (<DATA>) {
my ($protein, $year, $score) = split;
$scores_by_protein_and_year{$protein}{$year} = $score;
}
for my $protein (keys(%scores_by_protein_and_year)) {
my $scores_by_year = $scores_by_protein_and_year{$protein};
my $score = 0;
for my $year (sort { $a <=> $b } keys(%$scores_by_year)) {
$score += $scores_by_year->{$year};
say "$protein $year $score";
}
}
Это работает, даже если данные не сгруппированы / отсортированы.