Odpowiedź na to pytanie brzmi: perlfaq4 - odpowiedź na "How can I tell whether a certain element is contained in a list or array?".
Aby przeszukać perlfaq, możesz przeszukać listę wszystkich pytań pod numerem perlfaq używając swojej ulubionej przeglądarki.
Z wiersza poleceń można użyć przełącznika -q, aby wyszukać słowa kluczowe. byś znalazł odpowiedź szukając „liście”:
perldoc -q list
(fragmenty tej odpowiedzi wniesionego przez Anno Siegela i Brian d Foy)
Słysząc słowo „w” jest wskazanie Prawdopodobnie powinieneś użyć hasha, a nie listy lub tablicy do przechowywania twoich danych. Hashe zostały zaprojektowane, aby szybko i skutecznie odpowiedzieć na to pytanie. Tablice nie są.
W związku z powyższym istnieje kilka sposobów podejścia. W Perl 5.10 i później, można użyć operatora mecz inteligentnej, aby sprawdzić, że dany element jest zawarty w tablicy lub hash:
use 5.010;
if($item ~~ @array)
{
say "The array contains $item"
}
if($item ~~ %hash)
{
say "The hash contains $item"
}
z wcześniejszymi wersjami Perl, trzeba zrobić trochę więcej pracy. Jeśli masz zamiar dokonać tego zapytania wielokrotnie dowolnych ciągów znaków, najszybszym sposobem jest prawdopodobnie odwrócić oryginalną tablicę i utrzymać hash którego klucze są wartościami pierwszej tablicy za:
@blues = qw/azure cerulean teal turquoise lapis-lazuli/;
%is_blue =();
for (@blues) { $is_blue{$_} = 1 }
Teraz można sprawdzić czy $ is_blue {$ some_color}. Być może dobrym pomysłem byłoby przede wszystkim utrzymanie bluesa w haszyszu.
Jeśli wartościami są wszystkie małe liczby całkowite, można użyć prostej tablicy indeksowanej. Ten rodzaj tablicy zajmie mniej miejsca:
@primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31);
@is_tiny_prime =();
for (@primes) { $is_tiny_prime[$_] = 1 }
# or simply @istiny_prime[@primes] = (1) x @primes;
teraz sprawdzić, czy $ is_tiny_prime [$ some_number].
Jeśli wartości w pytaniu są liczbami całkowitymi zamiast strun, można zaoszczędzić sporo przestrzeni za pomocą bitowe ciągi zamiast:
@articles = (1..10, 150..2000, 2017);
undef $read;
for (@articles) { vec($read,$_,1) = 1 }
Teraz sprawdź czy vec ($ czytać, $ n, 1) jest prawda dla niektórych $ n.
Metody te gwarantują szybkie indywidualne testy, ale wymagają reorganizacji oryginalnej listy lub tablicy. Opłacają się tylko wtedy, gdy musisz przetestować wiele wartości w tej samej tablicy.
Jeśli testujesz tylko raz, standardowy moduł Lista :: Util eksportuje najpierw funkcję do tego celu. Działa poprzez zatrzymanie, gdy znajdzie element. Jest napisany w C dla szybkości, a jego odpowiednik Perl wygląda to podprogram:
sub first (&@) {
my $code = shift;
foreach (@_) {
return $_ if &{$code}();
}
undef;
}
Jeśli prędkość jest mało troski, wspólnej idiom używa grep w kontekście skalarnym (zwraca liczbę elementów, które przeszły jej stan) przejść przez całą listę. Ma to zaletę informowania o liczbie znalezionych pasujących elementów.
my $is_there = grep $_ eq $whatever, @array;
Jeśli chcesz wyodrębnić pasujące elementy, po prostu użyj grep w kontekście listy.
my @matches = grep $_ eq $whatever, @array;
nie jestem pewien, że widzę problemu zależność z listy :: Util. Jest to standard w Perlu i jeśli używasz go z qw/first/(jak zrobił Draegtun), importujesz tylko jeden podprogram. – Telemachus
To nie jest problem per se, to bardziej osobiste preferencje. – MaxVT
Nie ma problemu zależności od odpowiedzi List :: Util. Gdyby to był ja, byłaby to akceptowana odpowiedź. Niechęć do korzystania z podstawowych modułów uderza mnie jako preferencję zakorzenioną w przesądach. W tym przypadku grep {} jest prawie tak dobry. – singingfish