Obie metody w przyjętym stanowisku daje złą odpowiedź, jeśli @test = (undef, '')
. Oznacza to, że deklarują niezdefiniowaną wartość równą pustemu łańcuchowi znaków.
To może być dopuszczalne. Ponadto użycie grep
przechodzi przez wszystkie elementy tablicy, nawet jeśli wcześniej wykryto niedopasowanie, a użycie skrótu spowoduje dwukrotne zwiększenie liczby pamięci używanej przez elementy tablicy. Żadne z nich nie stanowi problemu, jeśli masz małe tablice. I, grep
prawdopodobnie będzie wystarczająco szybki dla rozsądnych rozmiarów list.
Jednak tutaj jest alternatywą, że 1) zwraca false dla (undef, '')
i (undef, 0)
, 2) nie zwiększa zużycie pamięci swojego programu i 3) zwiera, jak tylko rozbieżność zostanie znaleziony:
#!/usr/bin/perl
use strict; use warnings;
# Returns true for an empty array as there exist
# no elements of an empty set that are different
# than each other (see
# http://en.wikipedia.org/wiki/Vacuous_truth)
sub all_the_same {
my ($ref) = @_;
return 1 unless @$ref;
my $cmpv = \ $ref->[-1];
for my $i (0 .. $#$ref - 1) {
my $this = \ $ref->[$i];
return unless defined $$cmpv == defined $$this;
return if defined $$this
and ($$cmpv ne $$this);
}
return 1;
}
jednak użycie List::MoreUtils::first_index prawdopodobnie będzie szybciej:
use List::MoreUtils qw(first_index);
sub all_the_same {
my ($ref) = @_;
my $first = \ $ref->[0];
return -1 == first_index {
(defined $$first != defined)
or (defined and $_ ne $$first)
} @$ref;
}
Jakość rozwiązania naprawdę zależy od tego, co robisz w tej pętli foreach. Tak, istnieje wiele sposobów, aby to zrobić, ale dlaczego uważasz, że brakuje Twojego obecnego rozwiązania? –
Dlaczego nie kodujesz i nie publikujesz tego rozwiązania "foreach", abyśmy mogli komentować? – lexu
do wszystkich plakatów zainteresowanych o undef, nie zakładałbym "sprawdź czy każdy element tablicy jest tym samym ciągiem" zawiera możliwość undefs - definiowany jest "ciąg" z definicji :). (choć z pewnością warto się nad tym zastanowić) – ysth