Добавить еще один ключ к массиву хэшей из массива?

Допустим, есть массив хэшей, как показано:

@test = (
   {
      VAR1 => "1",
      VAR2 => "2",
      VAR3 => "3",
   },
   {
      VAR1 => "11",
      VAR2 => "22",
      VAR3 => "33",
   },
   {
      VAR1 => "111",
      VAR2 => "222",
      VAR3 => "333",
   },
);

И массив:

@test2 = ("4,44,444");

Как можно было бы добавить массив в виде пары ключ-значение в массив хэшей?

Съемка для конечного результата, который будет выглядеть так:

@result = (
   {
      VAR1 => "1",
      VAR2 => "2",
      VAR3 => "3",
      VAR4 => "4",
   },
   {
      VAR1 => "11",
      VAR2 => "22",
      VAR3 => "33",
      VAR4 => "44",
   },
   {
      VAR1 => "111",
      VAR2 => "222",
      VAR3 => "333",
      VAR4 => "444",
   },
);

Я новичок в Perl и не совсем уверен, как это можно сделать. Заранее спасибо.

3 ответа

Прежде всего, почему @test2 массив, если все, что он содержит, является строкой??? Чтобы это исправить, вы можете использовать следующее:

my @real_test2 = split(/,/, $test2[0]);

Почему вы используете хеши в качестве массивов???? Используйте AoA! Если бы у вас был AoA, это было бы

for my $i (0..$#result) {
   push @{ $result[$i] }, $real_test2[$i];
}

Если вы хотите придерживаться AoH, это очень похоже.

for my $i (0..$#result) {
   my $rec = $result[$i];
   my $key = 'VAR' . ( keys(%$rec) + 1 );
   $rec->{$key} = $real_test2[$i];
}

Или, если вы знаете, что ключ всегда будет одним и тем же, вы могли бы немного оптимизировать.

if (@result) {
   my $key = 'VAR' . ( keys(%{ $result[0] }) + 1 );
   for my $rec (@result) {
      $rec->{$key} = shift(@real_test2);
   }
}

Если вы действительно хотите использовать массив хэшей, то это сработает для вас.

for цикл повторяется по всем показателям @test а также @test2, Я использовал min функция от List::Util чтобы найти последний индекс короче из двух массивов. Это позволяет избежать падения конца одного или другого массива, если они имеют разную длину.

Ключ хеша с наибольшим номером находится с помощью регулярного выражения для извлечения числовой части каждого ключа вместе с max функция, также из List::Util, Следующий ключ, который нужно использовать, на один больше этого максимума, которому предшествует строка VAR,

Я использовал Data::Dump только чтобы показать результирующую структуру данных.

use strict;
use warnings;

use List::Util qw/ min max /;

my @test = (
  { VAR1 => 1,   VAR2 => 2,   VAR3 => 3 },
  { VAR1 => 11,  VAR2 => 22,  VAR3 => 33 },
  { VAR1 => 111, VAR2 => 222, VAR3 => 333 },
);

my @test2 = (4, 44, 444);
my $limit = min $#test, $#test2;

for my $i (0 .. $limit) {
  my $max = max map /(\d+)/, keys %{ $test[$i] };
  $test[$i]{'VAR'.++$max} = $test2[$i];
}

use Data::Dump;
dd \@test;

выход

[
  { VAR1 => 1, VAR2 => 2, VAR3 => 3, VAR4 => 4 },
  { VAR1 => 11, VAR2 => 22, VAR3 => 33, VAR4 => 44 },
  { VAR1 => 111, VAR2 => 222, VAR3 => 333, VAR4 => 444 },
]

Но если вы хотите использовать массив массивов, это будет выглядеть примерно так. Это очень похоже, за исключением того, что я могу просто использовать push вместо расчета индекса для следующего элемента массивов.

use strict;
use warnings;

use List::Util qw/ min /;

my @test = (
  [ 1, 2, 3 ],
  [ 11, 22, 33 ],
  [ 111, 222, 333 ],
);

my @test2 = (4, 44, 444);
my $limit = min $#test, $#test2;

for my $i (0 .. $limit) {
  push @{ $test[$i] }, $test2[$i];
}

use Data::Dump;
dd \@test;

выход

[[1 .. 4], [11, 22, 33, 44], [111, 222, 333, 444]]
$test[$_]{VAR4} = $test2[$_] foreach 0..$#test2;

Я должен согласиться с икегами, что это очень плохое использование хэшей.

Ключ к хэшу не должен быть численно значимым или значимым по порядку. Это должно быть мнемонически значимым. Он должен сказать вам, что 4.

Другие вопросы по тегам