Добавить еще один ключ к массиву хэшей из массива?
Допустим, есть массив хэшей, как показано:
@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.