2011-06-29 20 views
5

Używam mapy do wyodrębnienia pierwszego elementu z tablicy 2D. Oto mały fragment kodu.zrozumienie zachowania mapy

my $array = [ [1,11,111], [2,22], undef, [4] ]; 

my @firstList = map { (defined $_) && $_->[0] } @$array; 

W tym miejscu spodziewam się, że mapa zwróci tablicę zawierającą elementy o wartości undef lub pierwszy element elementu tablicy $ tablica.

ale wynik nie jest taki sam, jak się spodziewam. Dla undef, otrzymuję element typu "skalarny".

Jeśli zmienię wyciąg z mapy z następującym blokiem, to otrzymuję oczekiwany wynik.

my @firstList = map { $_->[0] } @$array; 

Proszę mi pomóc zrozumieć te dwa wyciągi z mapy.

Odpowiedz

4

Oba zwracają wynik ostatniej wykonanej operacji.

w pierwszym, gdy ocenia (defined $_) && $_->[0] dla undef, to widzi, że defined $_ jest fałszywy i zatrzymuje przetwarzanie logiczną wyrażenia. $_->[0] nie jest w ogóle analizowany w tym przypadku. defined $_ była ostatnią operacją ocenioną, a jej wynikiem był false, który, jak przypuszczam, jest reprezentowany przez 0.

Po drugie, jest to rzeczywista wartość od dziecka @$array, która jest tam, gdzie uzyskuje wartość undef.

+0

Mała poprawka: 'defined undef' zwraca' '''. – Dallaylaen

+2

Zastanawiam się, dlaczego undef -> [0] działa (nawet pod 'strict'). Okazuje się, że jest to [zindywidualizowane] (http://en.wikipedia.org/wiki/Autovivification), tj. Niejawnie ustawione na '[]' ** w oryginalnej tablicy **. – Dallaylaen

+1

@Dallaylaen: To wywołuje wystarczająco dużo osób, że CPAN ma moduł "autoworyzacji" na http://search.cpan.org/perldoc?autovivification, który pozwala ci go wyłączyć za pomocą komendy 'no autovivification;' –

0
map { (defined $_) && $_->[0] } 

faktycznie iteruje poprzez każdy element tablicy i stosuje jakąś funkcję lub wyrażenie. na zewnątrz jest to następująca funkcja: defined($_) && $_->[0] jeśli twoja komórka jest niezdefiniowana trzecia komórka twojej tablicy ocenia na defined(undef) && $->[0] (co równa się '' możesz spróbować ..), podczas gdy druga ocenia na 1 && $->[0], która równa się $ -> [0 ].

BTW, to także powód, dla którego działa drugie stwierdzenie, dla każdej komórki macierzy wybieramy pierwszą komórkę wewnętrzną.