URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 6378
[ Назад ]

Исходное сообщение
"Perl ключ HASHа это указательна на другой HASH возможно?"

Отправлено Krylov , 16-Апр-07 16:17 
Задача в следующем:
Есть ХЕШ %id ключом в этом хешэ является ID пользователя, значением - указатель на другой ХЭШ который всвою очередь содержит описания для данного ID пользователя.

Хочется создать на базе ХЭШа %id новый ХЭШ %new где в качестве ключа хеша %new должно быть значение хэша %id (то есть указатель на хэш с описанием), а в качестве значения должно быть одно из свойст хеша описаний. Все отлично до момента когда я пытаюсь разыменновать ключ хеша %new (см. код со строчкой !!!!).
Вот и возникает вопрос можно ли использовать указатель на хэш в качестве ключа хеша с последующим разыменование этого ключа?

Код:

my @users = qw(d a c b); # Id пользователя
my @size = qw(10 5 20 4);
my @color = qw(red black white green);
my %id = ();
my %new = ();

# формирование ХЭШа %id. Ключ хэша %id - id пользователя,
# значение указатель на хэш %sub содержаший описание
my $i = 0;
foreach my $id (@users){
            # хешь с описанием
            my %sub = (size => "$size[$i]", color => "$color[$i]");
            $i++;
            $id{$id} = \%sub;
    }
# ввыод на экран ключей и значений хэша %id с ключами и значениями
# хэша %sub
foreach my $user_id (keys %id){
    my $ptr = $id{$user_id};
    print "[$user_id => $id{$user_id}]\n";
    foreach my $sb (keys %$ptr){
            print ("\t$sb => $$ptr{$sb}\n");
    }
}
# формирование нового хэша %new из хэша %id
# ключом в хэше %new является указатель на хэш %sub, а значением -
# значение ключа 'size' хеша %sub.

print "\nNew array\n";
foreach my $adr (keys %id){
    my $ptr_adr = $id{$adr};
    $new{$ptr_adr} = $$ptr_adr{'size'};
}
# вывод на экран ключа=>значения хэша %new
foreach my $key (keys %new){
   print "[$key => $new{$key}]\n";
  
   # !!!!!!!!!!!!!!!!!!!!!
   # почему я немогу разыменновать указатель, который являтся ключом хэша
   print "[[%$key]]\n";
}

ВВЫОД ДАННОГО КОДА НА ЭКРАН:
[c => HASH(0x18d65f4)]
    color => white
    size => 20
[a => HASH(0x18d65e8)]
    color => black
    size => 5
[b => HASH(0x18d6690)]
    color => green
    size => 4
[d => HASH(0x18ea2e8)]
    color => red
    size => 10

New array
[HASH(0x18d6690) => 4]
[[%HASH(0x18d6690)]]         !!! тут должно быть green, 4
[HASH(0x18ea2e8) => 10]
[[%HASH(0x18ea2e8)]]         !!! итп
[HASH(0x18d65e8) => 5]
[[%HASH(0x18d65e8)]]         !!! итп
[HASH(0x18d65f4) => 20]
[[%HASH(0x18d65f4)]]         !!! итп


Содержание

Сообщения в этом обсуждении
"Perl ключ HASHа это указательна на другой HASH возможно?"
Отправлено A , 16-Апр-07 17:19 
нет. указатель нельзя использовать как ключь.
вернее можно, но при этом указатель превращается в строку и перестаёт быть указателем.
погу посоветовать сложить хэши-ключи в массив или в хэш и использвать индексы этого массива (или ключи этого хэша), как ключи.

"Perl ключ HASHа это указательна на другой HASH возможно?"
Отправлено Krylov , 16-Апр-07 18:37 
>нет. указатель нельзя использовать как ключь.
>вернее можно, но при этом указатель превращается в строку и перестаёт быть
>указателем.
>погу посоветовать сложить хэши-ключи в массив или в хэш и использвать индексы
>этого массива (или ключи этого хэша), как ключи.

Большое спасибо за ответ.

Если не сложно может вы подскажите как  правильней отсортировать хэш %user по значению ключа 'size' хеша %sub и при этом не потерять связь между хэшаем с описаниями пользователей (%sub) с хэшом %id?

то есть для моего примера после сортировки должно получиться следующие
user C size 20 (\%sub для узера C)
user D size 10 (\%sub для узера D)
user A size 5 (\%sub для узера A)
user B size 4 (\%sub для узера B)


"Perl ключ HASHа это указательна на другой HASH возможно?"
Отправлено A , 17-Апр-07 09:07 
>>нет. указатель нельзя использовать как ключь.
>>вернее можно, но при этом указатель превращается в строку и перестаёт быть
>>указателем.
>>погу посоветовать сложить хэши-ключи в массив или в хэш и использвать индексы
>>этого массива (или ключи этого хэша), как ключи.
>
>Большое спасибо за ответ.
>
>Если не сложно может вы подскажите как  правильней отсортировать хэш %user
>по значению ключа 'size' хеша %sub и при этом не потерять
>связь между хэшаем с описаниями пользователей (%sub) с хэшом %id?
>
>то есть для моего примера после сортировки должно получиться следующие
>user C size 20 (\%sub для узера C)
>user D size 10 (\%sub для узера D)
>user A size 5 (\%sub для узера A)
>user B size 4 (\%sub для узера B)

Честно пытался въехать что вам нужно минут десять, так и не смог :-) уж извиняйте :-)


"Perl ключ HASHа это указательна на другой HASH возможно?"
Отправлено Krylov , 17-Апр-07 12:07 
>>Честно пытался въехать что вам нужно минут десять, так и не смог
>:-) уж извиняйте :-)
Извеняюсь за то, что отнял у вас 10 минут своим плохим описанием вопроса. Но попытаюсь обяснить еще раз может на этот раз получиться :) если не сложно
Значит есть код:
-----------------------------------------------
my @users = qw(d a c b); # Id пользователя
my @size = qw(10 5 20 4);
my @color = qw(red black white green);
my %id = ();

my $i = 0;
foreach my $id (@users){
            # хешь с описанием
            my %sub = (size => "$size[$i]", color => "$color[$i]");
            $i++;
            $id{$id} = \%sub;
    }
-----------------------------------------------------
Этот код формирует хэш %id, в котором в качестве ключа используется id пользователя (см. @users содержащий id), а в качестве значения - указатель на хэш \%sub. Хэш %sub содержит для каждого пользователя его описание (color, size). Мне нужно отсортировать хэш %id по значению size хэша %sub. Другимим словами нужно получить отсортированый хэш %id, но сортировку производит по значению ключа size хэша %sub.


"Perl ключ HASHа это указательна на другой HASH возможно?"
Отправлено A , 17-Апр-07 17:18 
ну я не очень понял что такое сортированый хэш... но идею вроде уловил :-)
вот массив хэшей sub сортированых по sort:

my @sort = sort {$a->{'size'} <=> $b->{'size'}} values %id;

если нужно сохранить и id, то их можно добавить в sub-ы:

my %id2 = map {$_ => {%{$id{$_}}, 'id' => $_}} keys %id;


"Perl ключ HASHа это указательна на другой HASH возможно?"
Отправлено Krylov , 25-Апр-07 18:19 
Извеняюсь, что так долго не мог отписать Вам ответ
>ну я не очень понял что такое сортированый хэш... но идею вроде
>уловил :-)
>вот массив хэшей sub сортированых по sort:
>
>my @sort = sort {$a->{'size'} <=> $b->{'size'}} values %id;

Данный код то, что я хотел БОЛЬШОЕ СПАСИБО


>my %id2 = map {$_ => {%{$id{$_}}, 'id' => $_}} keys %id;
А вот в данном коде я не смог разобраться. Если вам не сложно поясните ваше выражение
$_ => {%{$id{$_}}, 'id' => $_}



"Perl ключ HASHа это указательна на другой HASH возможно?"
Отправлено A , 26-Апр-07 09:12 
>Извеняюсь, что так долго не мог отписать Вам ответ
>>ну я не очень понял что такое сортированый хэш... но идею вроде
>>уловил :-)
>>вот массив хэшей sub сортированых по sort:
>>
>>my @sort = sort {$a->{'size'} <=> $b->{'size'}} values %id;
>
>Данный код то, что я хотел БОЛЬШОЕ СПАСИБО
>
>
>>my %id2 = map {$_ => {%{$id{$_}}, 'id' => $_}} keys %id;
>А вот в данном коде я не смог разобраться. Если вам не
>сложно поясните ваше выражение
>$_ => {%{$id{$_}}, 'id' => $_}

как это это пояснить... :-)
<$_> => <{%{$id{$_}}, 'id' => $_}>
<прежний ключь> => <некий хэш>
что в хэше?
{<%{$id{$_}}>, <'id' => $_>}
это
{<весь прежний хзш>, <+новая пара 'id' => ключь>}

то есть у вас есть супер-хэш в котором хранятся хэши, я в каждый хэш добавил пару 'id' => "ключь супер-хэша".

это можно сделать вот для чего: при сортировке ключи супер-хэша пропадают (супер-хэш превращается в массив), если вам надо сохранить о них информацию, то имеет смысл преобразовать все хэши супер-хэша, добавив в них новую пару.

если ключь супер-хэша вам не нужен, то и забейте :-)


"Perl ключ HASHа это указательна на другой HASH возможно?"
Отправлено Krylov , 27-Апр-07 10:09 
>как это это пояснить... :-)
><$_> => <{%{$id{$_}}, 'id' => $_}>
><прежний ключь> => <некий хэш>
>что в хэше?
>{<%{$id{$_}}>, <'id' => $_>}
>это
>{<весь прежний хзш>, <+новая пара 'id' => ключь>}
>
>то есть у вас есть супер-хэш в котором хранятся хэши, я в каждый хэш добавил пару 'id' => "ключь супер-хэша".

Теперь все понятно большое Вам СПАСИБО!

>
>это можно сделать вот для чего: при сортировке ключи супер-хэша пропадают (супер-хэш
>превращается в массив), если вам надо сохранить о них информацию, то
>имеет смысл преобразовать все хэши супер-хэша, добавив в них новую пару.
>
>
>если ключь супер-хэша вам не нужен, то и забейте :-)