2

私自身の教育のために、いくつかの配列を変換して、それぞれがハッシュのキーに関連付けられ、それらすべてのハッシュが配列になるようにするための巧妙な方法は何ですか?

少しわかりやすくするために、次のような配列があるとします。

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;
}

もう少しパーリッシュ:

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 の精神に則り、他にどのような解決策が欠けているのでしょうか?

4

4 に答える 4

2

my @array = map { number => $n[$_], float => $f[$_], string => $s[$_] }, 0 .. $#n;

私はPerlの人ではなく、ただの提案です:)

于 2012-10-25T14:37:33.523 に答える
2

スライスを使用すると、実際には判読できません:

@{ $d[$_] }{qw/number float string/} = ($n[$_], $f[$_], $s[$_]) for 0 .. $#n;
于 2012-10-25T14:32:11.240 に答える
0

これはからのいくつかのユーティリティを使用しますList::MoreUtils

  • meshアレイのリストを統合するには
  • part配列を分割するには

また、次の引数が正の整数であるかどうかを示すために_POSINTfrom 。Params::Util

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ます。レイアウトは、データの構造を示します(コードのように)。

于 2012-10-25T17:31:51.160 に答える
0

このプログラムはあなたが必要とすることを行います

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;
于 2012-10-25T16:59:08.403 に答える