Более чистый способ хранения заменить скалярное хеш-значение на массив ref? - PullRequest
4 голосов
/ 08 апреля 2010

Я создаю хэш, в котором ключи, связанные со скалярами, не обязательно уникальны. Желаемое поведение таково: если ключ уникален, значением является скаляр. Если ключ не уникален, я хочу, чтобы значение было ссылкой на массив скаляров, связанных с ключом. Поскольку хеш создается итеративно, я не знаю, является ли ключ уникальным раньше времени. Прямо сейчас я делаю что-то вроде это:

if(!defined($hash{$key})){
   $hash{$key} = $val;
}
elseif(ref($hash{$key}) ne 'ARRAY'){
   my @a;
   push(@a, $hash{$key});
   push(@, $val);
   $hash{$key} = \@a;
}
else{
   push(@{$hash{$key}}, $val);
}

Есть ли более простой способ сделать это?

Ответы [ 2 ]

5 голосов
/ 08 апреля 2010

rjh прямо на деньги.

Я написал слишком много кода, который делает именно то, что вы описываете - хэш-значение является ссылкой на массив, если это не так. Пачки и пачки условной проверки типов. И вот однажды мне пришло в голову: «Почему я пишу всю эту чушь? Просто везде используй ссылку на массив, тупица», - сказал я себе. С того дня синие птицы летают с деревьев, чтобы петь мне, когда я гуляю в парке.

push @{$hash{$key}}, $val;

Это все, что тебе нужно сделать. Если ключ не существует, массив автоматически обновляется.

Если вы не любите autoviv и хотите быть явным, выполните:

$hash{$key} = [] unless exists $hash{$key};
push @{$hash{$key}}, $val;

Даже этот «многословный» подход намного короче.

1 голос
/ 08 апреля 2010
if(!defined($hash{$key})){
    $hash{$key} = $val;
}
elsif (ref($hash{$key}) ne 'ARRAY') {
    $hash{$key} = [ $hash{$key}, $val ];
}
else{
   push(@{$hash{$key}}, $val);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...