LINUX.ORG.RU

Создать массивы используя для них имена взятые из хэша

 ,


0

1

Шалом

Допустим есть такой хеш:

my %h = (
  'qwe' => 'q1',
  'asd' => 'q2',
  'zxc' => 'q3',
  'vbn' => 'q2',
  'rty' => 'q1',
  'fgh' => 'q3'
);

Размер хеша произвольный, ключи уникальные, количество значений 'qX' - конечно, но может изменяться по желанию пользователя. Собственно вопрос, нужно для всех значений qX создать одноименные массивы и упаковать в них, те ключи, которые на них ссылаются. Т.е. для примера выше, нужно получить


my @q1 = ('qwe', 'rty');
my @q2 = ('asd', 'vbn');
my @q3 = ('zxc', 'fgh');

Ты хочешь странного.

Если объявить все qX заранее, оно работать конечно будет.

#!/usr/bin/perl
#

use strict;
use warnings;
use Data::Dumper;

my %h = (
        'qwe' => 'asd',
        'foo' => 'bar',
);

my $string = '';
my (@asd, @bar);

for my $key (keys(%h)) {
        $string = $string."@".$h{"$key"}." = qw(".$key.");\n";
}

eval $string;
print Dumper(\@asd);
Если объявить нет возможности, то вроде бы что-то такое умеет модуль Safe.

Но я бы делать такое не стал. Это сильно неочевидно, имхо. Лучше сгенерить хеш массивов.

my %ah = (
 $h{"$key"} => \[$key, $key1, .., $keyN]
);

или написать функцию/метод, которая будет принимать на вход qN, а возвращать массив ссылающихся на него ключей.

shell-script ★★★★★
()

А не проще организовать данные в структуру типа

my %hash = (
  q1 => ['qwe', 'rty']
);
Anyway, вот тебе код, который так делает:
sub join_by_value {
  my ($hash) = @_;
 
  my %result = ();
  while (my ($key, $value) = each %$hash) {
    push @{$result{$value}}, $key;
  }
 
  return %result;
}

my %joined = join_by_value(\%h);

https://ideone.com/imAbhS

KennyMinigun ★★★★★
()
Ответ на: комментарий от shell-script

Можно, конечно забомбить и в переменные, если no strict qw(refs);

Но это будет убер говно, если только не принципальный подход.

KennyMinigun ★★★★★
()

Твой запрос похож на задачку для кодгольфа. Запости на jagc.org, например. Надеюсь тебе не для продакшена это надо, кисюк

anonymous
()
Ответ на: комментарий от KennyMinigun

По формулировке похоже как раз на no strict 'refs' - задачку. Бессмысленно и беспощадно, зато, хм, оригинально.

DRVTiny ★★★★★
()
Ответ на: комментарий от DRVTiny

Думаю, автор жаждёт такой ереси:

no strict 'refs';
my $arrName = 'my_array';
@{q<main::> . $arrName} = (1,2,3);

DRVTiny ★★★★★
()
Последнее исправление: DRVTiny (всего исправлений: 1)
Ответ на: комментарий от KennyMinigun

Вероятно проще, и я понимаю свою странный запрос.

Собственно задача не искусственная.

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

Из-за особенностей внешней проги, которая вызывается из воркера, при обработке данных из одного урла, она грузит только одно ядро процессора. Идея заключается в том, чтобы создать N очередей по количеству ядер на машине, раскидать по ним урлы и запустить параллельно N воркеров, которые будут все это дело перелопачивать.

Хеш из примера, это что-то вроде карты которая указывает на то в какую очередь нужно запихать этот урл.

У меня не было опыта в сложных структурах данных в Perl, поэтому допускаю, что что-то делаю неоптимально.

trancefer ★★
() автор топика
Ответ на: комментарий от trancefer

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

Только небольшая заметка: порядок обхода ключей хеша в Perl случайный, и потому порядок в результирующем хеше будет тоже разный.

KennyMinigun ★★★★★
()

опять попытка динамически генерировать переменные, вторая за месяц.
это какой-то тренд о котором я незнаю?

system-root ★★★★★
()
Ответ на: комментарий от KennyMinigun

Да, похоже это то что нужно, спасибо большое, сильно помогли :3

trancefer ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.