我的目标是从原始堆栈中删除 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)
{
}
}
}
我觉得有一种方法不需要堆栈密钥容器。我只是不知道......
答案 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 };