[英]Putting elements of arrays into array of hashes in Perl
僅出於我自己的教育目的,有什么巧妙的方法來轉換某些數組,以使每個數組都與哈希鍵關聯,而所有這些哈希最終都存儲在數組中?
為了使事情更清楚一點,假設我有一些像這樣的數組:
my @n = ( 1, 2, 3 );
my @f = ( 3.14, 1.21, 0.75 );
my @s = ( 'a', 'b', 'c' );
我想要一系列散列,如下所示:
my %h = ( number => 1, float => 3.14, string => 'a' );
簡單的C樣式迭代是一個顯而易見的解決方案:
for ( my $i = 0; $i < @n; $i++ ) {
my %h = ();
$h{number} = $n[$i];
$h{float} = $f[$i];
$h{string} = $s[$i];
push @a, \%h;
}
稍許Perlish:
for (0..$#n) {
push @c, { number => $n[$_], float => $f[$_], string => $s[$_] };
}
或者,如果我想簡潔明了,不關心銷毀數組:
for (0..$#n) {
push @a, { number => shift @n, float => shift @f, string => shift @s };
}
並與List::MoreUtils
:
use List::MoreUtils qw (each_array);
my $it = each_array @n, @f, @s;
while ( my ($n, $f, $s) = $it->() ) {
push @a, { number => $n, float => $f, string => $s };
}
因此,本着TMTOWTDI的精神,我還缺少其他解決方案嗎?
使用切片無法真正可讀:
@{ $d[$_] }{qw/number float string/} = ($n[$_], $f[$_], $s[$_]) for 0 .. $#n;
my @array = map { number => $n[$_], float => $f[$_], string => $s[$_] }, 0 .. $#n;
我不是Perl的家伙,只是一個建議:)
該程序可以滿足您的要求
use strict;
use warnings;
my @n = ( 1, 2, 3 );
my @f = ( 3.14, 1.21, 0.75 );
my @s = ( 'a', 'b', 'c' );
my @data;
for my $i (0 .. $#n) {
@{$data[$i]}{ qw/ number float string / } = map $_->[$i], \(@n, @f, @s);
}
use Data::Dump;
dd \@data;
產量
[
{ float => 3.14, number => 1, string => "a" },
{ float => 1.21, number => 2, string => "b" },
{ float => 0.75, number => 3, string => "c" },
]
或者,您可能更喜歡使用List::MoreUtils
庫的each_array
函數的解決方案。 該程序的輸出與上述我之前的解決方案的輸出相同。
use strict;
use warnings;
use List::MoreUtils 'each_array';
my @n = ( 1, 2, 3 );
my @f = ( 3.14, 1.21, 0.75 );
my @s = ( 'a', 'b', 'c' );
my $iter = each_array(@n, @f, @s);
my @data;
while ( my @values = $iter->() ) {
my $i = $iter->('index');
@{ $data[$i] }{ qw/ number float string / } = @values;
}
use Data::Dump;
dd \@data;
這使用了List::MoreUtils
一些實用程序
也是來自Params::Util
_POSINT
來告訴下一個參數是否為正整數。
use List::MoreUtils qw<mesh part>; # integrate and partition arrays
use Params::Util qw<_POSINT>; # test number positive
# accept size number if positive int, otherwise we will be returning pairs.
sub by (@) {
my $num = &_POSINT ? shift : 2;
my $i = -1;
return part { int( ++$i / $num ) } @_;
}
my @n = qw< 1 2 3 >;
my @f = qw< 3.14 1.21 0.75 >;
my @s = qw< a b c >;
my @fields = qw<number float string>;
my @results = map { +{ mesh @fields, @$_ } } by 3 => mesh @n, @f, @s;
當然,使用此方法,您可以像這樣列出數據:
my @results
= map { +{ mesh @fields, @$_ } }
by 3 => qw< 1 3.14 a
2 1.21 b
3 0.75 c
>
;
並跳過第一個mesh
。 布局指示數據的結構(如代碼所示)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.