Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Слияние хэшей


Автор: meridian 13.4.2011, 12:19
Привет!
Задача сложить два хэша.  При печати выводит правильные значения, а результат какой-то не тот. Помогите разобраться, плиз.
Я так понял, если просто выполнить %res = (%hash1, %hash2), то значения %hash2 перетрут %hash1.

Код

%hash1 =
(
        id1 => "str1",
        id2 => "str2",
        id3 => "str3"
);

%hash2 =
(
        id1 => "str6",
        id2 => "str7",
        id3 => "str8"
);

%res=(); # получить типа id1 = "str1;str6" и т.д.


#наполнение хэшей (размеры одинаковые)
...

#слияние
while (my ($key, $h1) = each %hash1)
{
    if (exists $hash2{ $key } )
    {
         print "$key hash1 : @{ $hash1{ $key } }\n";
         print "$key hash2 : @{ $hash2{ $key } }\n";
         
         $h2= $hash2{ $key };
         $res{$key} = $h1. ";" . $h2;

         print "$key res : @{ $res{ $key } }\n";
    }
}


И второй вопрос. Можно ли сделать, что бы значение %hash1 добавлялось к %hash2, например
%hash1 =
(
        id1 => "str1",
        id2 => "str2",
        id3 => "str3"
);

%hash2 =
(
        id1 => "str6",
        id2 => "str7",
        id3 => "str8"
);

результат 
%res =
(
        id1 => "str1", "str6"
        id2 => "str2", "str7"
        id3 => "str3", "str8"
);

Автор: IceSunrise 13.4.2011, 12:37
meridian,  привет
твой код выдал мне вот такой результат
Код

$res = {
          'id1' => 'str1;str6',
          'id2' => 'str2;str7',
          'id3' => 'str3;str8'
        };


Это не то, что нужно?

Автор: meridian 13.4.2011, 13:22
Привет, это то что нужно, но у меня что-то не дает, странно.
Все равно пасиб, сейчас попробую еще раз.

Автор: meridian 13.4.2011, 13:38
Сделал вот что,
заполнил хэши 

Код

push ( @{ $hash1{$_} }, "да" ) foreach @id;
push ( @{ $hash2{$_} }, "нет" ) foreach @id;


по идее должны получиться значения "да;нет", но при печати получаю следующее

Код

id1 hash1 : да
id1 hash2: нет
id1 res : 
 

т.е. res пустое


Автор: meridian 13.4.2011, 14:16
Со второй часть вопроса разобрался - создание хэшей массивов. Добавление всех значений к первому хэшу
Код

push(@{ $hash1{$key} }, "new value");


Автор: IceSunrise 13.4.2011, 14:47
meridian,  а какую версию перла ты используешь?
Дело в том, что вот эта твоя строчка
Код

print "$key hash1 : @{ $hash1{ $key } }\n";

 у меня печатает:
Код

id1 hash1 :


Правильный синтаксис в данном случае такой:
Код

print "$key hash1 : @{[ $hash1{ $key } ]}\n";


Но не понятно, зачем здесь так хитрить, пиши просто:
Код

print "$key hash1 : $hash1{$key}\n";


Для вывода в консоль всего хеша используй модуль Data::Dumper, очень просто и удобно:
Код

use Data::Dumper;
print Dumper(\%res);

Автор: meridian 13.4.2011, 16:20
Цитата(IceSunrise @  13.4.2011,  13:47 Найти цитируемый пост)

Но не понятно, зачем здесь так хитрить, пиши просто:
Выделить всёБез подсветки
1:
    
print "$key hash1 : $hash1{$key}\n";


пробовал так , тогда получается
id1 res: ARRAY(0x1f9ad50)
id2 res: ARRAY(0x1fa6a9c)

Добавлено через 7 минут и 10 секунд
А вот еще, при получении значений из хэша, который имеет несколько значений, вид

$res{"id1"} = [ str1, str2, str3 ] и т.д.

как перебирать значения из хэша по ключу ?

Автор: IceSunrise 13.4.2011, 16:31
meridian
Вот твой код, который работает как ты хочешь smile
Код

%hash1 = (
    id1 => "str1",
    id2 => "str2",
    id3 => "str3"
);

%hash2 = (
    id1 => "str6",
    id2 => "str7",
    id3 => "str8"
);

%res=();

while (my ($key, $h1) = each %hash1)
{
    if (exists $hash2{$key})
    {
         print "HASH1 KEY='$key'; VALUE='$hash2{$key}'\n";
         print "HASH2 KEY='$key'; VALUE='$hash2{$key}'\n";

         $h2 = $hash2{$key};
         $res{$key} = $h1 . ";" . $h2;

         print "RES   KEY='$key'; VALUE='$res{$key}'\n";
    }
}

use Data::Dumper;
print Dumper(\%res);



Вот его вывод:
Код

HASH1 KEY='id1'; VALUE='str6'
HASH2 KEY='id1'; VALUE='str6'
RES   KEY='id1'; VALUE='str1;str6'
HASH1 KEY='id2'; VALUE='str7'
HASH2 KEY='id2'; VALUE='str7'
RES   KEY='id2'; VALUE='str2;str7'
HASH1 KEY='id3'; VALUE='str8'
HASH2 KEY='id3'; VALUE='str8'
RES   KEY='id3'; VALUE='str3;str8'
$VAR1 = {
          'id1' => 'str1;str6',
          'id2' => 'str2;str7',
          'id3' => 'str3;str8'
        };


Но учти, что в результирующий хеш попадут только ключи из первого хеша (hash1). Если во втором хеше (hash2) будут ключи, которых нет в первом, то и в результирующем хеше их не будет.

Автор: meridian 13.4.2011, 16:33
Цитата(meridian @  13.4.2011,  15:20 Найти цитируемый пост)
 вот еще, при получении значений из хэша, который имеет несколько значений, вид

$res{"id1"} = [ str1, str2, str3 ] и т.д.

как перебирать значения из хэша по ключу ? 



Вот такой будет работать ?
for my $key ( keys %res ) {
    print "$key = ".join( ', ', @{ $res{$key} } );
}

Добавлено через 2 минуты и 8 секунд
Цитата(IceSunrise @  13.4.2011,  15:31 Найти цитируемый пост)
Но учти, что в результирующий хеш попадут только ключи из первого хеша (hash1). Если во втором хеше (hash2) будут ключи, которых нет в первом, то и в результирующем хеше их не будет. 


Спасибо!  Это я знаю, в моем случае так и надо, т.е. что не входит - отбрасываем.
 

Автор: meridian 13.4.2011, 17:50
IceSunrise спасибо! Вопрос решен.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)