2013-03-01 72 views
5

我有一個大數組的引用,並且某些元素(從某個索引到最後)需要用於在數據庫中插入新行。Perl:切片數組,不創建一個全新的數組

有無論如何我可以創建一個更大的數組的一部分的參考嗎? 或者我可以用DBI的execute_array函數使用數組的一部分,而不需要Perl在後臺拷貝數據負載?

這裏就是我想更有效地做到:

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

(哦,我明白了,參數是一個「列」列表,其中每列是該列的值的數組的引用。) – ikegami 2013-03-01 16:14:09

+3

看起來你的黑魔法攻擊我的雞。呃...炸雞... – ikegami 2013-03-01 16:30:02

+0

我一直在想。難道我不能只是這樣做:'$ arrayref + = $ index; $ sh-> execute_array({},$ arrayref);' 我知道這個確切的代碼不會工作,因爲perl不是C,但這並不意味着我無法完成同樣的事情。 – Jonathon 2013-03-01 19:26:29

回答

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

類似於

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

注意分配其拷貝片的所有元素。我們能避免複製標量如下:

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

現在,我們只是複製(其中任何字符串)指針(SV*),而不是整個標量。

+0

所以這應該工作。 並且做一些測試,對數組的返回引用是針對第一個數組中的相同元素的(您可以通過更改其中任何一個元素來更改它們)。 – Jonathon 2013-03-01 18:37:10

+0

稍微優雅些,如果你只做一次: 'sub {\ @_;} - >(@ {$ arrayref} [2..4]);' – Jonathon 2013-03-01 18:49:37

+1

更緊湊,也許,但我故意沒有使用它,因爲1)它缺乏我所使用的自我記錄屬性,2)在教學情況下難以閱讀,3)'sub {my @a = @_; \ @a} - >(...)'本來就不那麼容易閱讀,4)我想你會在多個地方使用它。 PS,那'''是無用的。 – ikegami 2013-03-01 18:56:59

1

參數傳遞在Perl開始作爲「按引用傳遞」。如果您想知道是否進行了值複製,請查看源代碼。

在這種情況下,execute_array的第二行定義將@_引用的值複製到名爲@array_of_arrays的詞法中。

在光明的一面,這是一個淺的副本。 (至少據我已經看了。)

5

陣列片返回多個值,並有@印記:

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" 

切片將返回標量的列表(=數組!)。但是,這本身不是副本:

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

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

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

所以這是非常有效的。

如果你想創建一個新的陣列(或數組引用),你必須複製的值:

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

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

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

語法\@array[1..2]將返回引用列表在片每一個元素,但不是參考切片。

相關問題