Превратить массив в хеш, где значения ключей имеют неодинаковую длину - PullRequest
0 голосов
/ 11 октября 2011

Мне нравится превращать массив в хеш.Однако значения имеют неодинаковую длину для каждой клавиши.

Допустим, у меня есть

my @array = qw( A 0 B 1 2 3 4 c 5 d 6 7);

Теперь мне нравится использовать буквы в качестве клавиш, а для каждой такой буквы / клавиши следующий номер(s) как их значения.Поэтому @array следует преобразовать в %hash следующим образом

my %hash = ( A => [0],
             B => [1, 2, 3, 4],
             c => [5],
             d => [6, 7]
    );

Для меня сложность заключается в неравной длине значения каждого ключа.

Ответы [ 4 ]

6 голосов
/ 11 октября 2011

Вот способ сделать это:

#!/usr/local/bin/perl 
use Data::Dump qw(dump);
use strict;
use warnings;

my @array = qw( A 0 B 1 2 3 4 c 5 d 6 7);
my %hash;
my $key;
foreach (@array) {
    if (/^\D+$/) {
        $key = $_;
        $hash{$key} = [];
    } else {
        push @{$hash{$key}}, $_;
    }
}
dump %hash;

Вывод:

("A", [0], "c", [5], "d", [6, 7], "B", [1 .. 4])
4 голосов
/ 11 октября 2011

Первый ответ для этого конкретного примера, а затем некоторые комментарии

my $hash = {};
my @array = qw( A 0 B 1 2 3 4 c 5 d 6 7);
my $key;
foreach (@array) {
    if (/\D/) {
        $key = $_;
        next;
    } else {
        push @{$hash->{$key}}, $_;
    }
}

А если вы хотите поиграть в отладчике:

$ perl -de 0

  DB<18>  @array = qw( A 0 B 1 2 3 4 c 5 d 6 7);
  DB<19> $hash={}
  DB<20> foreach(@array){if(/\D/){$key=$_;next}else{push @{$hash->{$key}},$_}}
  DB<21> x $hash
0  HASH(0x347e568)
  'A' => ARRAY(0x348fee8)
    0  0
  'B' => ARRAY(0x346f188)
    0  1
    1  2
    2  3
    3  4
  'c' => ARRAY(0x34cefb0)
    0  5
  'd' => ARRAY(0x346f1e8)
    0  6
    1  7

Комментарии: если ваши ключи не дают информацию о том, является ли значение скалярным или массивом ref, лучше иметь все значения одного типа (в данном случае arrayref)

Вы хотели бы проверить, имеет ли последний ключ значение, и решить, хотите ли вы инициализировать undef или нет.

2 голосов
/ 11 октября 2011

Чуть проще, чем ранее предоставленные решения:

my @array = qw( A 0 B 1 2 3 4 c 5 d 6 7);
my %hash;
my $values;
for (@array) {
   if (/\D/) {
      $values = $hash{$_} = [];
   } else {
      push @$values, $_;
   }
}
2 голосов
/ 11 октября 2011

Или используя map:

my @a = qw{a 1 2 3 b 4 5 6 C 7 8 9};
my ($key, %h);
map {  /^[a-z]$/i  and  $key = $_  or  push(@{$h{$key}}, $_)  } @a;

Разве Perl не забавен?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...