2013-03-01 7 views
5

Mam odwołanie do dużej tablicy, a niektóre elementy (od jakiegoś indeksu do końca) muszą się przyzwyczaić do wstawienia nowych wierszy do bazy danych.Perl: Pokrój tablicę, bez tworzenia całej nowej tablicy

Czy mogę mimo to utworzyć odniesienie do części większej tablicy? Albo w inny sposób mogę użyć części tablicy z funkcją execute_array DBI, bez tego, że Perl kopiuje mnóstwo danych w tle?

Oto, co chcę zrobić wydajniej:

$sh->execute_array({}, [ @{$arrayref}[@indexes] ]); 
+0

(oh Widzę, argumenty są listą "kolumn", gdzie każda kolumna jest odnosnikiem tablicy wartości dla tej kolumny.) – ikegami

+3

Wygląda na to, że twój Czarny Mag zaatakował mojego kurczaka. ummm ... smażony kurczak ... – ikegami

+0

Zastanawiam się. Czy nie mogę po prostu zrobić coś takiego: '$ arrayref + = $ index; $ sh-> execute_array ({}, $ arrayref); ' Wiem, że ten dokładny kod nie zadziała, ponieważ Perl to nie C, ale to nie znaczy, że nie mogę tego zrobić. – Jonathon

Odpowiedz

4
$sh->execute_array({}, [ @{$arrayref}[@indexes] ]); 

jest podobny do

sub new_array { my @a = @_; \@a } 
$sh->execute_array({}, new_array(@{$arrayref}[@indexes])); 

Zanotować przydziału, której kopie wszystkich elementów w przekroju. Możemy uniknąć kopiowania skalary następująco:

sub array_of_aliases { \@_ } 
$sh->execute_array({}, array_of_aliases(@{$arrayref}[@indexes])); 

Teraz jesteśmy po prostu kopiując wskaźniki (SV*) zamiast całych skalarów (i dowolny ciąg tamże).

+0

To powinno zadziałać. Wykonując niektóre testy, zwrócone odwołanie do tablicy dotyczy tych samych elementów w pierwszej tablicy (można je zmienić, zmieniając jeden element w jednym z nich). – Jonathon

+0

Nieco bardziej elegancko, jeśli robisz to tylko raz: 'sub {\ @_;} -> (@ {$ arrayref} [2..4]);' – Jonathon

+1

Mniejsze, może, ale celowo nie wykorzystaj to, bo 1) nie ma właściwości samokonujących tego, czego użyłem, 2) trudniej jest odczytać w sytuacji nauczania, 3) 'sub {my @a = @_; \ @a} -> (...) "byłby jeszcze trudniejszy do odczytania i 4) Pomyślałem, że użyjesz go w więcej niż jednym miejscu. PS, że ';' jest bezużyteczne. – ikegami

1

przekazywanie parametrów w Perl zaczyna się jak „przejściu przez odniesienie”. Jeśli chcesz się dowiedzieć, czy została wykonana kopia wartościowa, spójrz na kod źródłowy.

W tym przypadku definicja kopii drugiej linii execute_array „s wartości odwołuje @_ do leksykalne nazwie @array_of_arrays.

Po jasnej stronie jest to płytka kopia. (Przynajmniej tak daleko, jak szukałem.)

5

Array plastry zwracać wiele wartości i mają @ sigil:

my @array = (1, 2, 3, 4); 

print join " ", @array[1..2]; # "2 3" 

my $aref = [1, 2, 3, 4]; 

print join " ", @{$aref}[1..3]; # "2 3 4" 

Plasterek zwróci listę (= tablicę!) Skalarów. Jednak nie jest to kopia per se:

my @array = (1, 2, 3, 4); 

for (@array[1..2]) { 
    s/\d/_/; # change the element of the array slice 
} 

print "@array"; # "1 _ _ 4" 

Jest to dość wydajne.

Jeśli chcesz utworzyć nową tablicę (lub odwołania do tablicy), trzeba skopiować wartości:

my @array = (1, 2, 3, 4); 

my @slice = @array[1..2]; 

my $slice = [ @array[1..2] ]; 

składni \@array[1..2] zwróci listę odnośników do każdego elementu w kawałkach, ale nie odniesienie do plasterka.

Powiązane problemy