Привет,
есть несколько хэшей, некоторые ключи у них совпадают. хочу объединить хэши, чтобы ключи остались уникальными, а все значения стали массивами.
Или я не туда пошёл... вообщем у меня такие входные данные
я получаю разномастную статистику в таком виде $hash{$ident}="some1"
из кучи сборщиков статистики получаю пачку хэшей, где в большинстве ключи $ident совпадают, но есть и встречающиеся по 1-му разу.
в глобальный сборщик пытаюсь передать примерно такое:
$hash{$ident_total}=@array, где @array=(hash1{$ident},hash2{$ident}) и если значения отсутствуют, то просто ноль.
но что-то ничего в голову не лезет, подсказку не дадите? застрял на этапе формирования массива из значений всех уникальных ключей хэшей.
>Привет,
>есть несколько хэшей, некоторые ключи у них совпадают. хочу объединить хэши, чтобы
>ключи остались уникальными, а все значения стали массивами.
>Или я не туда пошёл... вообщем у меня такие входные данные
>я получаю разномастную статистику в таком виде $hash{$ident}="some1"
>из кучи сборщиков статистики получаю пачку хэшей, где в большинстве ключи $ident
>совпадают, но есть и встречающиеся по 1-му разу.
>в глобальный сборщик пытаюсь передать примерно такое:
>$hash{$ident_total}=@array, где @array=(hash1{$ident},hash2{$ident}) и если значения отсутствуют, то просто ноль.
>но что-то ничего в голову не лезет, подсказку не дадите? застрял на
>этапе формирования массива из значений всех уникальных ключей хэшей.# данные
%h1=qw/a 1 b 2/;
%h2=qw/a 3 c 4/;
# решение
%h=();
foreach (\%h1, \%h2) {
while (($a, $b)=each(%$_)) {
push @{$h{$a}}, $b
}
}
>>Привет,
>>есть несколько хэшей, некоторые ключи у них совпадают. хочу объединить хэши, чтобы
>>ключи остались уникальными, а все значения стали массивами.
>>Или я не туда пошёл... вообщем у меня такие входные данные
>>я получаю разномастную статистику в таком виде $hash{$ident}="some1"
>>из кучи сборщиков статистики получаю пачку хэшей, где в большинстве ключи $ident
>>совпадают, но есть и встречающиеся по 1-му разу.
>>в глобальный сборщик пытаюсь передать примерно такое:
>>$hash{$ident_total}=@array, где @array=(hash1{$ident},hash2{$ident}) и если значения отсутствуют, то просто ноль.
>>но что-то ничего в голову не лезет, подсказку не дадите? застрял на
>>этапе формирования массива из значений всех уникальных ключей хэшей.
>
># данные
>%h1=qw/a 1 b 2/;
>%h2=qw/a 3 c 4/;
># решение
>%h=();
>foreach (\%h1, \%h2) {
> while (($a, $b)=each(%$_)) {
> push @{$h{$a}}, $b
> }
>}ага, спасибо за подсказку, вроде получается
foreach $k (sort keys %h){print "$k: @{$h{$k}}\n" }
>$hash{$ident_total}=@array, где @array=(hash1{$ident},hash2{$ident}) и если значения
> отсутствуют, то просто ноль.Насколько нужно хранить раздельные значения? Нельзя просто сложить их, если они числовые?
foreach $h (\%hash1 \%hash2 ...) {
foreach $k (keys %{ $h }) {
$$h{$k} =~ /clean up regex/;
$global_stat{$k} += $1; # ну, или что там ты получил
}
}
>>$hash{$ident_total}=@array, где @array=(hash1{$ident},hash2{$ident}) и если значения
>> отсутствуют, то просто ноль.
>
>Насколько нужно хранить раздельные значения? Нельзя просто сложить их, если они числовые?Хранить обязательно, складывать нельзя. Возможно я сначала сумбурно обьяснил, попытаюсь заново, на простом примере:
получаю 2 хэша такого содержения.
%h_in{$user_mail}=$messages_in #получено сообщений
%h_out{$user_mail}=$messages_out #отправлено сообщений
какой-то конкретный $user_mail может отсутствовать в одном из кэшей, если он не полуали или не отправлял сообщения.Хочу получить новый хэш, где ключ $user_mail, а значение @data=($messages_in,messages_out)
причём если значения нет (ключ+значение отсутствует в одном из кэшей) то в массив всё равно ставим 0.>foreach $h (\%hash1 \%hash2 ...) {
> foreach $k (keys %{ $h }) {
>
> $$h{$k} =~ /clean up regex/;
> $global_stat{$k} += $1;
> # ну, или что там ты получил
> }
>}в принципе A мне показал как это делать, на ваш пример заставил задуматься, а так ли мне нужен массив в значениях, проще будет в дальнейщем работать со строкой, которую получу из сложения значений в хэшах как строк, а не чисел. что-то типа $global_stat{$k} .= $$h{$k};
у меня ещё вопрос по хэшам:
как посмотреть определённый ключ по конкретному значению без цикла перебора всего хэша?допустим есть готовый хэш вида $h1{$mail}=$uid ключ $mail, значение $uid
в цикле ниже я заполняю другой хэш $h2{$mail}=$var из строки где всегда присутствует $uid, но не всегда $mail. мне же ключом нужен именно $mail.
тогда, если при разборе не удалось выяснить $mail, но известен $uid то я хочу сделать так:
$h2{где ключ, ключ из $h1 полученный по значению $uid}=$var
вот тут и застрял :( делать reverse %h1 нельзя, потому что uid уникаленесли это невозможно, придётся изобретать конструкцию замены названий ключей в %h2
я, честно говоря, не смог понять что надо :-) тут нигде опечатка не закралась?
>я, честно говоря, не смог понять что надо :-) тут нигде опечатка
>не закралась?ммм, попробую ещё раз c примером.
есть готовый хэш вида $h1{cyrus@domen.ru}=cyrus_user в переменных так: $h1{$mail}=$uid
далее, другой хэш заполняю в такой виде $h2{cyrus@domen.ru}='какое-то значение' (в переменных: $h2{$mail}=$size).заполнение %h2 идёт из такой строки
mail=cyrus@domen.ru uid=cyrus size=123
где берутся $mail и $sizeоднако, строка может принять вид:
mail=<> uid=cyrus size=123тогда, чтобы получить $mail, нужно в %h1 найти по $uid ключ $mail и подставить полученный ключ $mail, как ключ в %h2. вот что-то такое:
$h2{где ключ, значение ключа из %h1 полученный по значению $uid}=$size
кажется понял :-)
а почему вы пишите
> делать reverse %h1 нельзя, потому что uid уникален
как раз с уникальным-то можно
>кажется понял :-)
>а почему вы пишите
>> делать reverse %h1 нельзя, потому что uid уникален
>как раз с уникальным-то можноуникальный то он для задачи..
#ключ $mail, значение $uid
my %h1=('cyrus@domen.ru' => 'cyrus',
'admin@domen.ru' => 'cyrus');
my %h2=reverse %h1;
while(($key,$value) = each %h1){print "$key -> $value\n";}
while(($key,$value) = each %h2){print "$key => $value\n";}$ ./2test.pl
cyrus@domen.ru -> cyrus
admin@domen.ru -> cyrus
cyrus => cyrus@domen.ruесли сделаю reverse, тоесть значения станут ключами и наоборот, то тогда в данной хэше повторяющийся ключ $uid будет иметь только одно значение (какое-то там по индексам хэша, сам перл придумает).
>>кажется понял :-)
>>а почему вы пишите
>>> делать reverse %h1 нельзя, потому что uid уникален
>>как раз с уникальным-то можно
>
>уникальный то он для задачи..
>
>#ключ $mail, значение $uid
>my %h1=('cyrus@domen.ru' => 'cyrus',
> 'admin@domen.ru' => 'cyrus');
>my %h2=reverse %h1;
>while(($key,$value) = each %h1){print "$key -> $value\n";}
>while(($key,$value) = each %h2){print "$key => $value\n";}
>
>$ ./2test.pl
>cyrus@domen.ru -> cyrus
>admin@domen.ru -> cyrus
>cyrus => cyrus@domen.ru
>
>если сделаю reverse, тоесть значения станут ключами и наоборот, то тогда в
>данной хэше повторяющийся ключ $uid будет иметь только одно значение (какое-то
>там по индексам хэша, сам перл придумает).хотя тут я опять стал думать в контексте задачи..
если поле mail пустое, то не всё ли равно какой mail по uid подставлять? ;)в конечной статистике оперирование пойдёт по $uid-ам и их привязке к отделам.
вообщем всю концепцию переработаю, но вопрос остаётся в силе.заполнение %h3 идёт из такой строки
mail=cyrus@domen.ru uid=cyrus size=123
где берутся $mail, $uid и $size
однако, строка может принять вид:
mail=<> uid=cyrus size=123
тогда я хочу вот так (выше для %h2 сделал reverse):
if ($mail "<>") {
$h3{$h2{$uid}}+=$size;
}
на что получаю:
Use of uninitialized value in concatenation (.) or stringвот собственно как в %h3 сделать ключом значение, полученное из %h2 по ключу?
равно как и первоначальная задача была в %h3 сделать ключом ключ из %h1, полученный по значению.
все вопросы снимаются, внимательно прочитал
http://www.opennet.me/docs/RUS/perl_hash/perl_hash-perl.html.gzвсем спасибо