Ищете более эффективный способ отфильтровать perl-хеш - PullRequest
2 голосов
/ 24 февраля 2012

Моя цель - удалить из необработанного стека записи, которые не в списке хороших ключей .

Как мне добиться этого наиболее эффективным способом? Код, над которым я сейчас работаю, чувствует себя перетаскиваемым. Я открыт для предложений.

Обратите внимание, что значения могут быть смехотворно большими.

Вот мои данные:

# 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 Ответ

8 голосов
/ 24 февраля 2012

Вот любимая цитата Ларри Уолла : «Выполнение линейного сканирования по ассоциативному массиву похоже на попытку забить кого-то до смерти с помощью загруженного Узи».

Вы должны знать о ломтиках хеша . С помощью которого вы можете делать то, что ниже. Конечно, это означает, что у вас есть список точных ключей, которых у вас нет. Но для иллюстрации:

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

Однако, если вы не хотите копировать значения, вы можете сделать что-то более сложное, например:

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

Используется интеллектуальное сопоставление с 5.10.

Конечно, вам придется адаптироваться к этому. Предполагая, что вы смотрите только на среднюю клавишу [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 };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...