mam kod jak poniżej:Porównywanie wielu ciągów w Perl
if ($var eq "str1" || $var eq "str2" || $var eq "str3")
{
...
}
Czy istnieje jakikolwiek celu optymalizacji tego. chcę coś takiego:
if ($var eq ["str1" || "str2" || "str3"]) {...}
mam kod jak poniżej:Porównywanie wielu ciągów w Perl
if ($var eq "str1" || $var eq "str2" || $var eq "str3")
{
...
}
Czy istnieje jakikolwiek celu optymalizacji tego. chcę coś takiego:
if ($var eq ["str1" || "str2" || "str3"]) {...}
zależności od zawartości strun, regex jest bardzo wygodne:
if ($var =~ /^(str1|str2|str3)$/) { … }
W przeciwnym razie, można grep na listę:
if (grep { $var eq $_ } qw{str1 str2 str3}) { … }
dziękuję bardzo .. Pierwsze wyrażenie zadziałało, ale z usuniętymi nawiasami: if ($ var = ~/^ str1 | str2 | str3 $ /) – sundar
@ user988967, Nie, to nie działa. Bez parensów będzie pasować do 'str1A',' Astr2A' i 'Astr3'. – ikegami
@ikegami, tak, masz rację. dzięki ... Jeszcze jedno pytanie. Używam "use strict" u góry mojego kodu. więc radzisz mi użyć "?:" – sundar
W języku Perl 5.10 lub lepszym:
if ($var ~~ [qw(str1 str2 str3)]) { ...}
Operator ~~
wykonuje między swoimi argumentami smart match.
+1; Nie miałem pojęcia, że ten operator istnieje. –
@MarceloCantos: *** "Operator smartmatch jest eksperymentalny, a jego zachowanie może ulec zmianie." *** Zalecam, aby go unikać – Borodin
@Borodin: Generalnie unikam Perla, ale +1 do heads-upa. –
Zastosowanie List::MoreUtils qw{any}
use List::MoreUtils qw{any};
if (any { $var eq $_ } 'str1', 'str2', 'str3') {
...
}
To może być szybsze niż przy użyciu grep
ponieważ List::MoreUtils::any
wykończeń wcześnie, gdy stwierdzi mecz natomiast grep
może zbudować kompletną listę meczów. Mówię "może", ponieważ Perl mógł zoptymalizować if (grep ...
. Może nie. Ale List::MoreUtils::any
kończy się wcześniej i jest bardziej opisowy niż idiom if (grep ...
.
Zrób skrót, który ma klucze do wszystkich ciągów chcesz dopasować
my %matcher;
@matcher{qw{str1 str2 str3}} =();
if (exists $matcher{$var}) {
...
}
Ma to tę wadę, że czas uruchamiania systemu oraz koszt pamięci używane do mieszania, ale przewagę jest to, że czas meczu jest bardziej podobny do O (log N). Więc jeśli masz dużo różnych wartości $var
, które chcesz przetestować, może to być ogólnie lepsze.
Zrób regex, który pasuje do wszystkich ciągów
if ($var =~ m/^str[123]$/so) {
...
}
OK, więc jest to w porządku, jeśli struny są dosłownie qw{str1 str2 str3}
, ale co jeśli to jest lista dowolnych ciągów?
Można użyć Regexp::Assemble, aby połączyć listę wyrażeń regularnych w jedno zoptymalizowane wyrażenie regularne.
[Regexp :: Assemble] (http://p3rl.org/Regexp::Assemble) nie jest potrzebny w nowszych Perlach, ponieważ regexps mają teraz [Trie optimization] (http://perldoc.perl.org/perl5100delta.html # Trie-optymalizacja-literowych-naprzemiennych-naprzemiennych). –
Jestem pół-żartem, ale będzie to zrobić:
use Quantum::Superpositions;
if ($x == any($a, $b, $c)) { ... }
Zobacz także tym Perl Monks thread
Aby uzyskać listę łańcuchów o stałej długości, konwersja listy do mieszania. Jest to szczególnie przydatne, jeśli zamierzasz sprawdzać listę kilka razy i jeśli lista się powiększy.
Jeśli przez "optymalizację" rozumie się "szybsze działanie", pierwsza wersja jest optymalna (jeśli zamówisz ciągi tak, aby były najbardziej prawdopodobne). – Mat