私はperlに以下の文字列を持っています:
my $string = xyz;1;xyz;2;a;2;b;2
以下のように、この文字列の後にハッシュを作成したい:
my @array =split /;/,$string;
$hash{xyz} =(1,2);
$hash{b}=(2);
$hahs{a}=(2);
これを行うためのPerlの方法は何ですか?
私はperlに以下の文字列を持っています:
my $string = xyz;1;xyz;2;a;2;b;2
以下のように、この文字列の後にハッシュを作成したい:
my @array =split /;/,$string;
$hash{xyz} =(1,2);
$hash{b}=(2);
$hahs{a}=(2);
これを行うためのPerlの方法は何ですか?
my $string = "xyz;1;xyz;2;a;2;b;2";
my %hash;
push @{$hash{$1}}, $2 while $string =~ s/^(\w+);(\d+);?//g;
実際
push @{$hash{$1}}, $2 while $string =~ m/(\w+);(\d+);?/g;
それはあなたの元の弦を食い尽くさないので、より良いでしょう。
同じキーの複数の値を配列参照にする場合、それを行う1つの方法は次のようになります。
my @values = split /;/, $string;
my %hash;
while( @values ) {
my $key = shift @values;
my $val = shift @values;
if ( exists $hash{$key} && !ref $hash{$key} ) {
# upgrade to arrayref
$hash{$key} = [ $hash{$key}, $val ];
} elsif ( ref $hash{$key} ) {
push @{ $hash{$key} }, $val;
} else {
$hash{$key} = $val;
}
}
あなたのデータでは、これは次のような構造になります
{
'a' => '2',
'b' => '2',
'xyz' => [
'1',
'2'
]
};
map
Drats:繰り返しキーがあります...またはで何かしたかったのですgrep
。
これは非常に簡単に理解できます。
my $string = "xyz;1;xyz;2;a;2;b;2";
my @array = split /;/ => $string;
my %hash;
while (@array) {
my ($key, $value) = splice @array, 0, 2;
$hash{$key} = [] if not exists $hash{$key};
push @{$hash{$key}}, $value;
}
このプログラムは、キーが文字列に一緒に含まれていない場合でも機能します。たとえばxyz
、他の値のペアで区切られている場合でも、以下は機能します。
my $string = "xyz;1;a;2;b;2;xyz;2";
これは、の値を単一のメンバー配列への参照にすることを$hash{b}=(2);
意味すると想定しています。$hash{b}
あれは正しいですか?
おそらくこれを行う最も簡単な(標準の)方法はList::MoreUtils::natatime
use List::MoreUtils qw<natatime>;
my $iter = natatime 2 => split /;/, 'xyz;1;xyz;2;a;2;b;2';
my %hash;
while ( my ( $k, $v ) = $iter->()) {
push @{ $hash{ $k } }, $v;
}
しかし、私がおそらくもう一度やりたいと思う部分を抽象化する...
use List::MoreUtils qw<natatime>;
sub pairs {
my $iter = natatime 2 => @_;
my @pairs;
while ( my ( $k, $v ) = $iter->()) {
push @pairs, [ $k, $v ];
}
return @pairs;
}
sub multi_hash {
my %h;
push @{ $h{ $_->[0] } }, $_->[1] foreach &pairs;
return wantarray ? %h : \%h;
}
my %hash = multi_hash( split /;/, 'xyz;1;xyz;2;a;2;b;2' );