2

Data::Dumper出力が次のようなhashref があるとします。

    $VAR1 = {
        foo_0 => 'foo_zero',
        foo_1 => 'foo_one',
        bar_0 => 'bar_zero',
        bar_1 => 'bar_one'
    }

以下に示すように、キーに基づいてこのハッシュを 2 つに分割したいのですが、これを行う方法がわかりません。

    $VAR1 = {
        foo_0 => 'foo_zero',
        foo_1 => 'foo_one'
    }、
    $VAR2 = {
        bar_0 => 'bar_zero',
        bar_1 => 'bar_one'
    }

最初のハッシュのキーは一致/foo_[\d]/し、2 番目のハッシュのキーは一致し/bar_[\d]/ます。

これを行う方法を親切に教えていただければ(または検索キーワードをいくつか教えてください)、いただければ幸いです。

よろしく、
クリストファー・スミス

4

3 に答える 3

2

私はあなたのハッシュ参照がであると仮定しています$foo_reffooハッシュキーがaでも。でもない場合にどうなるかについては述べていませんbar。次の3つのいずれかを実行できます。

  • 参照をハッシュする必要があります。fooキーの1つと他のすべてのキーの1つ。
  • fooキーでもキーでもないキーを捨てbarます。(これは私がしたことです)。
  • すべての非fooおよび非barキーを格納する3番目のハッシュがあります。

以下のプログラム:

#! /usr/bin/env perl

use strict;
use warnings;
use feature qw(say);
use Data::Dumper;

my $foo_re = qr/^foo_/;
my $bar_re = qr/^bar_/;

my $foo_ref = {
    foo_0 => "foo_zero",
    foo_1 => "foo_one",
    bar_0 => "bar_zero",
    bar_1 => "bar_one",
};

my $bar_ref = {};
foreach my $key (keys %{$foo_ref}) {
    if (not $key =~ $foo_re) {

    # Remove if clause to store all non-foo keys in $bar_re
    $bar_ref->{$key} = $foo_ref->{$key} if $key =~ $bar_re;
    delete $foo_ref->{$key}
    }
}

say Dumper $foo_ref;
say Dumper $bar_ref;
于 2012-05-18T01:31:52.480 に答える
2

これまでに投稿された他のソリューションは機能しますが、迅速で汚れています。入力パターンが変わると変更する必要があり、2 つのパターンのみを想定しています。この一般化されたソリューションは、そのような問題に悩まされることはありません。変更する必要はなく、任意の数のパターンを使用できます。

sub classify_hashref {
    my ($href, %p) = @_;
    my $r;
    for my $hkey (keys %{ $href }) {
        for my $pkey (keys %p) {
            $r->{$pkey}{$hkey} = $href->{$hkey}
                if $hkey =~ $p{$pkey};
        }
    }
    return $r;
}

my $h = {
    foo_0 => 'foo_zero',
    foo_1 => 'foo_one',
    bar_0 => 'bar_zero',
    bar_1 => 'bar_one'
};
classify_hashref($h, foo_like => qr/^foo_/, looks_like_bar => qr/^bar_/);
# {
#     looks_like_bar => {
#         bar_0 => 'bar_zero',
#         bar_1 => 'bar_one'
#     },
#     foo_like => {
#         foo_0 => 'foo_zero',
#         foo_1 => 'foo_one'
#     }
# }
于 2012-05-18T06:41:08.400 に答える
1

すべてのハッシュキーには、提供されている2つのパターンのいずれかがあると想定しています。そうでない場合は、自分が持っているものと期待するものをより正確に指定する必要があります。ダンプ
の出力を処理したい場合は、に適した正しい形式であると想定しています。出力を中に入れて :evalq()

# ...

my $VAR1;

eval q(
    $VAR1 = {
        foo_0 => 'foo_zero',
        foo_1 => 'foo_one',
        bar_0 => 'bar_zero',
        bar_1 => 'bar_one'
    }
);

my $h1 = {};
my $h2 = {};

for my $k ( keys %{$VAR1} ) {
    if ( $k =~ /foo_\d/  ) {
        $h1->{$k} = $VAR1->{$k};
        next;
    }

    $h2->{$k} = $VAR1->{$k};  # the remaining  /bar_\d/ case
}

# use your new $h1 and $h2 hasrefs
# ...

2つの新しいhasref$h1とを取得し$h2ます。これらの2つ以外のケースがある場合は、最初のケースだけでなく、
全員をの中に入れる必要があります。 これは完全なスクリプトではなく、単なるスニペットです。if

于 2012-05-18T01:26:21.463 に答える