【问题标题】:Perl: Slice an array, without creating a whole new arrayPerl:对数组进行切片,而不创建一个全新的数组
【发布时间】:2013-03-01 15:10:53
【问题描述】:

我有一个大数组的引用,一些元素(从某个索引到末尾)需要习惯于在数据库中插入新行。

无论如何我可以创建对更大数组的一部分的引用吗? 或者另一种方法我可以使用带有 DBI 的 execute_array 函数的数组的一部分,而无需在后台使用 Perl 复制加载数据?

这是我想要更有效地做的事情:

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

【问题讨论】:

  • (哦,我明白了,args 是一个“列”列表,其中每一列都是对该列的值数组的引用。)
  • 看起来你的黑魔法师攻击了我的鸡。嗯……炸鸡……
  • 我一直在想。我能不能只做这样的事情:$arrayref += $index; $sh->execute_array({}, $arrayref); 我知道这个确切的代码不会工作,因为 perl 不是 C,但这并不意味着我不能完成同样的事情。
  • @JonathonWisnoski 不,Perl 引用是 not 指针。但是,您可以通过shift @$arrayref(或splice @$arrayref, 0, $number)从引用的数组中删除第一个元素,然后使用修改后的数组。这将非常接近您的代码。

标签: performance perl slice


【解决方案1】:

数组切片返回多个值并具有@ 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"

切片将返回一个标量列表(!= 一个数组)。但是,这本身不是副本:

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] 将返回对切片中每个元素的引用列表,但不返回切片的引用。

【讨论】:

    【解决方案2】:
    $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*) 而不是整个标量(以及其中的任何字符串)。

    【讨论】:

    • 所以这应该有效。并且做一些测试,返回的数组引用是针对第一个数组中的相同元素的(您可以通过更改其中任何一个元素中的一个元素来更改两者)。
    • 稍微优雅一点,如果你只这样做一次:sub{\@_;}->(@{$arrayref}[2..4]);
    • 也许更紧凑,但我故意不使用它,因为 1)它缺乏我使用的东西的自我记录属性,2)在教学情况下更难阅读,3)@ 987654326@ 会更不容易阅读,并且 4) 我想你会在不止一个地方使用它。 PS,那个;没用。
    【解决方案3】:

    Perl 中的参数传递以“按引用传递”开始。如果您想知道是否进行了值复制,请查看源代码。

    在这种情况下,execute_array 的第二行的定义将@_ 引用的值复制到一个名为@array_of_arrays 的词法中。

    从好的方面来说,这是一个浅拷贝。 (至少在我看来。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-26
      • 2021-12-26
      • 2014-04-16
      • 2018-10-25
      • 2022-01-18
      • 2017-11-30
      • 1970-01-01
      • 2013-04-20
      相关资源
      最近更新 更多