寻找更有效的方法来过滤perl散列 [英] Looking for a more efficient way to filter out a perl hash

查看:96
本文介绍了寻找更有效的方法来过滤perl散列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是从好的键列表中从原始堆栈中移除 not 中的记录。

我如何以最有效的方式实现这一目标?我目前正在编写的代码感觉拖累。我很乐意提供建议。



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

以下是我的数据:

 #主数据容器
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',
);

#仅堆栈密钥容器
我的@stack_keys =(
'a1〜a2〜a3',
'b1〜b2〜b3',
'c1〜c2〜c3',
'd1〜d2〜d3',
'e1〜e2〜e3',
);

#有效密钥容器
my @good_keys =(
'a2',
'c2',
'e2',
);

这是我目前正在使用的代码:

  foreach my $ good_key(@good_keys)
{
foreach my $ stack_key(@stack_keys)
{
my @stack = split(/〜/,$ stack_key);
if $ $



$ b $ $ $ $ $ $

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

解决方案

拉里·沃尔最喜欢的引文:对联合阵列进行线性扫描就像试图用一个装载的Uzi将某人关在一起。

您应该了解散列片一>。你可以用它来做下面的事情。当然,这意味着你有一个确切键的列表,你不知道。但要说明:

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

然而,如果你不想复制这些值,你可以做一些更复杂的事情,比如这:

 删除@raw_stack {grep {$ _!~~ @good_keys}键%raw_stack}; 

这使用智能匹配



当然,你必须从中适应。假设你只看中间键 [1] ,它看起来像我在一个键中寻找一个模式所以创建一个。

  my $ regex = join('|',sort {length($ b)< =>长度($ a )或$ a cmp $ b} @good_keys); 
$ regex = qr {〜($ regex)〜};
删除@raw_stack {grep {!m / $ regex /}键%raw_stack};


My goal is to remove from the raw stack the records that are not in the good keys list.

How do I achieve this in the most efficient manner? The code I'm currently working on feels dragging. I'm open for suggestions.

Please do note that the values could get ridiculously large.

Here's my data:

# 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',
);

Here's the code I'm currently working on:

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

        }
    }
}

I feel like there's a way to not need the stack keys container. I just don't know how...

解决方案

There is that favorite quote by Larry Wall: "Doing linear scans over an associative array is like trying to club someone to death with a loaded Uzi."

You should know about hash slices. With which you can do what's below. Of course that implies that you have a list of exact keys, which you don't. But to illustrate:

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

However if you don't want to copy the values, you could do something a little more complicated like this:

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

This uses smart matching from 5.10.

Of course you'll have to adapt from that. Assuming that you are only looking at the middle key [1], it looks to me like you're looking for a pattern in a key, so create one.

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 };

这篇关于寻找更有效的方法来过滤perl散列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆