Looking for a more efficient way to filter out a p

2019-05-19 23:48发布

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...

标签: perl hash
1条回答
再贱就再见
2楼-- · 2019-05-20 00:36

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 };
查看更多
登录 后发表回答