#perl #hash
#perl #хэш
Вопрос:
Я хочу подсчитать значения массива внутри хэша и добавить их в хэш. Мой код выглядит следующим образом:
while(my $line=<$fh>) {
$timestamp = $1 if $line=~ /^s*<timestamp>(.*)</;
$timestamp =~ s/^(dddd-dd-dd)T.*s*$/$1/;
$errorCode= $1 if $line=~ /^s*<errorCode>(.*)</;
$hash{$timestamp} = {} unless($hash{$timestamp});
$hash{$timestamp}{$errorCode} = [] unless($hash{$timestamp}{$errorCode});
push @{$hash{$timestamp}{$errorCode}}, $1 if $line =~ /<errorText>(.*)</;
}
Вывод
'2019-04-05' => { '5005' => [
'Dies ist kein aktives Konto',
'Dies ist kein aktives Konto'
],
'7112' => [
'Eingabefelder nicht richtig gefuellt.',
'Eingabefelder nicht richtig gefuellt.',
'Eingabefelder nicht richtig gefuellt.'
],
}
Я хотел бы иметь что-то вроде этого:
'2019-04-05' => { '5005' => { 'Dies ist kein aktives Konto' => 2 },
'7112' => { 'Eingabefelder nicht richtig gefuellt.' => 3 },
}
Кто-нибудь может мне помочь с этим? Заранее спасибо.
Комментарии:
1. привет, Мельпомена, да, правильно. Я отредактирую его
2. Совет: ВСЕГДА используйте
use strict; use warnings;
3. Совет: используйте анализатор XML, такой как XML::LibXML! Это не сложнее, и это избавит вас от стольких головных болей!
4. Совет:
my ($date) = $timestamp =~ /^([^T])/;
иmy ($date) = split(/T/, $timestamp);
гораздо более чистые способы извлечения даты.5. Совет: вы используете
$errorCode
, даже если вы не установили его!!! Использоватьmy ($error_code) = $line =~ /<errorCode>(.*)</ ? $1 : "";
Ответ №1:
Вы можете просто сделать
while (my $line=<$fh>) {
$timestamp = $1 if $line=~ /^s*<timestamp>(.*)</;
$timestamp =~ s/^(dddd-dd-dd)T.*$/$1/;
$errorCode= $1 if $line=~ /^s*<errorCode>(.*)</;
$hash{$timestamp}{$errorCode}{$1} if $line =~ /<errorText>(.*)</;
}
Нет необходимости проверять наличие промежуточных структур и создавать их вручную. Об этом позаботится автозаполнение.
Просто добавьте еще один уровень доступа к хэш-ключу и увеличьте значение. В итоге вы получите количество значений.