2

假设我有一个 hashref,其Data::Dumper输出如下所示:

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

我想根据它的键将此哈希分成两部分,如下所示,但我不知道如何执行此操作:

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

第一个哈希的键匹配/foo_[\d]/,而第二个哈希的键匹配/bar_[\d]/

如果您能告诉我如何做到这一点(或提示我一些搜索关键字),我将不胜感激。

问候,
克里斯托弗·史密斯

4

3 回答 3

2

我假设您的哈希引用是$foo_ref. 您没有说明如果您的哈希键既不是 a 也不是 a 会发生foo什么bar。你可以做以下三件事之一:

  • 您必须对引用进行哈希处理。键之一foo和所有其他键之一。
  • 你扔掉既不是foo钥匙也不是钥匙的bar钥匙。(这就是我所做的)。
  • 您有第三个散列,它存储所有非 foo 和非 bar 键。

下面的程序:

#! /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

到目前为止发布的其他解决方案都有效,但又快又脏。当输入模式改变时它们需要改变,并且只假设两种模式。这个通用的解决方案不会受此影响:它不需要更改,并且可以使用任意数量的模式。

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

我假设您所有的哈希键都具有提供的两种模式之一。如果没有,那么您应该更准确地指定您拥有什么以及您期望什么。
如果您想处理转储的输出,我还假设它具有适合的正确格式eval。只需将您的输出放入q()

# ...

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 个新的 hasrefs$h1$h2.
如果您有除这 2 个以外的其他情况,则应将每个人都放在一个if中,而不仅仅是第一个。
这不是一个完整的脚本,只是一个片段。

于 2012-05-18T01:26:21.463 回答