Как скопировать ключи из хэша в массив без дубликатов? - PullRequest
2 голосов
/ 05 июля 2011

Если у меня есть массив и хэш, подобные этим

#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;

my @a = qw/a b c d e/;
my %h = (a => 1, b => 1, f => 1, g => 1);

и я хотел бы получить @a, содержащий все ключи из %h, и ни один элемент в массиве не должен появляться более одного раза.

Как это можно сделать, поскольку exists не работает с массивами?

Ответы [ 4 ]

6 голосов
/ 05 июля 2011

Если у вас есть Perl 5.10 и более поздние версии, вы можете использовать интеллектуальное сопоставление (~~):

for my $key (keys %h) {        
    push @a, $key unless $key ~~ @a;      
}

В противном случае List::Util first может помочь:

for my $key (keys %h) {        
    push @a, $key unless first { $_ eq $key } @a;      
}
5 голосов
/ 05 июля 2011

Преобразуйте нужные значения в хеш-ключи, затем извлеките их

my %foo = map { $_ => 1  } @a, keys %h;
print sort keys %foo;
5 голосов
/ 05 июля 2011

Вы можете использовать функцию List::MoreUtils uniq:

use List::MoreUtils qw( uniq );

@a = uniq @a, keys %h;
4 голосов
/ 05 июля 2011

Как насчет этого (по общему признанию разрушительного для `% h):

delete @h{ @a }; # delete all keys of h already in @a
push @a, keys %h; # push remaining keys onto @a

Таким образом, @a сохраняет свой порядок и просто добавляет неповторяющиеся ключи в %h.

Несколько слов о разрушительности. Приведенный выше пример иллюстрирует некоторые концепции того, что можно сделать, когда вы можете позволить себе быть разрушительным. И удаление, безусловно, не более разрушительно, чем выход за рамки лексической переменной.

Проблема может быть решена путем простого копирования ее в другой хеш, прежде чем сузить хеш до тех ключей, которые не найдены в @a.

my %h2 = %h;
delete @h2{ @a };
push @a, keys %h2;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...