#perl #hashmap
#perl #hashmap
Вопрос:
Я инициализирую хэш-таблицу следующим образом:-
my %AllCountStats = ();
foreach my $Log (@LogList) {
foreach my $Func (keys %AllFuncNames) {
push @{$AllCountStats{$Log}}, {Func=>$Func,Count=>0};
}
}
print Dumper (%AllCountStats);
Вывод дампера выглядит следующим образом:-
$VAR1 = {
'log.1' => [
{
'Count' => 0,
'Func' => 'Function A'
},
{
'Func' => 'Function B',
'Count' => 0
},
}
'log.2' => [
{
'Count' => 0,
'Func' => 'Function A'
},
{
'Count' => 0,
'Func' => 'Function X'
},
};
Теперь мне нужно выполнить итерацию по хэшу массива хэшей и хирургически обновить значения Count для каждой функции. Используя приведенный выше пример, какую команду мне выполнить, чтобы обновить log.1 в Func=Function Значение Count до чего-то нового (т. Е. Не 0)? Вот пример того, где / как я пытаюсь выполнить обновление…
foreach $Log (@LogList) {
foreach (sort {$a->{SCmdLineNum} <=> $b->{SCmdLineNum}} @{$SweepStats{$Log}}) {
$SCmd = $_->{SCmd};
my $inner = $AllCountStats{$Log}{$SCmd}{Count};
$inner->{$_} for keys %$inner;
}
}
Но это не работает. Когда $inner фактически становится $AllCountStats{log .1} {Функция B} {Count}, как я могу аккуратно обновить его значение Count?
Комментарии:
1. Откуда
%SweepStats
берутся? Пожалуйста, попробуйте отредактировать код, чтобы мы могли запустить его и воспроизвести вашу проблему. Что вы подразумеваете под «не работает»?2. Привет, @choroba, тебе действительно не нужно беспокоиться о%SweepStats — главный вопрос заключается в том, как хирургически обновить поля подсчета в %AllCountStats . Когда я пытаюсь выдать этот $inner-> {$_} , он сообщает, что предыдущая строка является недопустимой ссылкой на хэш, поэтому я предполагаю, что она отформатирована неправильно.
3. Re » вам действительно не нужно беспокоиться о%SweepStats «, хорошо, верно, но нам нужно знать, какой
Count
из них вы пытаетесь увеличить для данного элемента@{$SweepStats{$Log}}
.4. Совет: это
sort
бесполезно. Ничто в цикле не заботится о порядке посещения элементов.
Ответ №1:
$AllCountStats{$Log}
это ссылка на массив, но вы рассматриваете его как ссылку на хэш.
Это
$AllCountStats{$Log}{$SCmd}{Count}
должно быть
$AllCountStats{$Log}[$i]{Count}
Неясно, какое значение вы хотите $i
. Мы вернемся к этому.
Далее, следующее не имеет смысла:
my $inner = $AllCountStats{$Log}[$i]{Count};
$inner->{$_} for keys %$inner;
$inner
это просто число, а не ссылка на хэш. Вы хотите
my $inner = $AllCountStats{$Log}[$i]
$inner->{Count};
или просто
$AllCountStats{$Log}[$i]{Count};
Вернуться к $i
. Мое лучшее предположение заключается в том, что вы хотите увеличить Count
значение записи, Function
значение которой равно $SCmd
.
for my $log_name (@LogList) {
my $log = $AllCountStats{$log_name};
for my $stats_rec (@{$SweepStats{$Log}}) { # Useless sort removed.
my $SCmd = $stats_rec->{SCmd};
for my $log_rec (@$log) {
$log_rec->{Count} if $log_rec->{Function} eq $SCmd;
}
}
}
Если это так, было бы проще, если бы вы построили %AllCountStats
так, чтобы это выглядело
my %AllCountStats = (
'log.1' => {
'Function A' => 0,
'Function B' => 0,
},
...
);
Тогда все, что вам нужно, это
for my $log_name (@LogList) {
my $log = $AllCountStats{$log_name};
for my $stats_rec (@{$SweepStats{$Log}}) {
$log->{ $stats_rec->{SCmd} };
}
}
Комментарии:
1. спасибо за предложение! Ваши предположения точны, и ваша рекомендация сработала. Я прошу прощения за то, что у меня не было более чистого исходного сообщения, но было больно извлекать суть проблемы (много сложных журналов, проприетарные детали, тысячи функций и т. Д., Но Нужно было изменить только количество).
Ответ №2:
Пожалуйста, посмотрите следующий фрагмент кода (должно быть легко понять)
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
my $log = 'log.1';
my $func = 'Function A';
my $count = 5;
my %AllCountStats = (
'log.1' => [
{
'Count' => 0,
'Func' => 'Function A'
},
{
'Func' => 'Function B',
'Count' => 0
}
],
'log.2' => [
{
'Count' => 0,
'Func' => 'Function A'
},
{
'Count' => 0,
'Func' => 'Function X'
}
]
);
for ( @{$AllCountStats{$log}} ) {
$_->{'Count'} = $count if $_->{'Func'} eq $func;
}
say Dumper(%AllCountStats);
Комментарии:
1. @’Polar Bear’ большое спасибо — это именно то, что мне нужно было сделать, и оно работает как надо!
Ответ №3:
Второй уровень структуры, похоже, представляет собой массив, а не хэш. Для этого нужны квадратные скобки.
В %AllCountStats
, вы храните числа под ключом «Count». Это число сохраняется в $inner
, и затем вы пытаетесь разыменовать его как хэш.
Вместо этого увеличьте значение напрямую:
$AllCountStats{$Log}[$SCmd]{Count}
Комментарии:
1. (Я сомневаюсь
$SCmd
, что это число. Я думаю, что это еще не все)2. Правильный $ SCmd на самом деле является сложной текстовой строкой — необходимо использовать index() != -1 для проверки совпадений и т. Д.
3. Тогда я не понимаю, как вы хотите использовать сложную текстовую строку для индексации в массив.