寻找一种更有效的方法来过滤掉perl哈希

时间:2012-02-24 03:49:00

标签: perl hash

我的目标是从原始堆栈中删除 good keys 列表中的记录。

如何以最有效的方式实现这一目标?我目前正在处理的代码感觉拖延。我愿意接受建议。

请注意,这些值可能会变得非常大。

这是我的数据:

# Main data container
my %raw_stack = (
    'a1~a2~a3' => 'dat1~dat2',
    'b1~b2~b3' => 'dat1~dat2',
    'c1~c2~c3' => 'dat1~dat2',
    'd1~d2~d3' => 'dat1~dat2',
    'e1~e2~e3' => 'dat1~dat2',
);

# Container of stack keys only
my @stack_keys = (
    'a1~a2~a3',
    'b1~b2~b3',
    'c1~c2~c3',
    'd1~d2~d3',
    'e1~e2~e3',
);

# Container of valid keys
my @good_keys = (
    'a2',
    'c2',
    'e2',
);

以下是我目前正在处理的代码:

foreach my $good_key (@good_keys)
{
    foreach my $stack_key (@stack_keys)
    {
        my @stack = split(/~/, $stack_key);
        if ($stack[1] eq $good_key)
        {

        }
    }
}

我觉得有一种方法需要堆栈密钥容器。我只是不知道......

1 个答案:

答案 0 :(得分:8)

favorite quote by Larry Wall:“对一个关联数组进行线性扫描就像是试图用装满Uzi的人来杀死某人。”

您应该了解hash slices。您可以使用它来执行以下操作。当然,这意味着您有一个确切键列表,而您没有。但要说明:

my %clean_hash;
@clean_hash{ @good_keys } = @raw_stack{ @good_keys };

但是如果你不想复制这些值,你可以做一些像这样复杂的事情:

delete @raw_stack{ grep { $_ !~~ @good_keys } keys %raw_stack };

这使用5.10中的smart matching

当然,你必须适应这一点。假设您只查看中间键[1],我认为您正在寻找键中的模式,因此请创建一个。

my $regex = join( '|', sort { length( $b ) <=> length( $a ) or $a cmp $b } @good_keys );
$regex    = qr{~($regex)~};
delete @raw_stack{ grep { !m/$regex/ } keys %raw_stack };