【问题标题】:What is the difference between push and unshift in Perl?Perl 中的 push 和 unshift 有什么区别?
【发布时间】:2011-01-18 17:50:59
【问题描述】:

谁能解释一下为什么 push 的行为如下所示?

基本上,我正在尝试打印由pushunshift 填充的数组的值。

当我尝试使用数组索引打印由push 填充的数组内容时,它总是打印数组顶部的元素,而由unshift 填充的数组根据数组索引打印数组的内容。我不明白为什么。

不移位

#!/usr/bin/perl
@names = ("Abhijit","Royal Enfield","Google");
@numbers=();
$number=1;
$i=0;
foreach $name (@names) {
    #print $_ . "\n";
    $number=$number+1;
    #push(@numbers,($number));
    unshift(@numbers,($number));
    print("Array size is :" . @numbers . "\n");
    $i=$i+1;
    print("Individual Elements are:" . @numbers[i] . "\n");
    pop(@numbers);
}

rhv:/var/cl_ip_down>./run.sh
Array size is :1
Individual Elements are:2
Array size is :2
Individual Elements are:3
Array size is :3
Individual Elements are:4

没有取消移位

#!/usr/bin/perl
@names = ("Abhijit","Royal Enfield","Google");
@numbers=();
$number=1;
$i=0;
foreach $name (@names) {
    #print $_ . "\n";
    $number=$number+1;
    push(@numbers,($number));
    #unshift(@numbers,($number));
    print("Array size is :" . @numbers . "\n");
    $i=$i+1;
    print("Individual Elements are:" . @numbers[i] . "\n");
}

rhv:/var/cl_ip_down>./run.sh
Array size is :1
Individual Elements are:2
Array size is :2
Individual Elements are:2
Array size is :3
Individual Elements are:2

/没有弹出/

#!/usr/bin/perl
@names = ("Abhijit","Royal Enfield","Google");
@numbers=();
$number=1;
$i=0;
foreach $name (@names) {
    #print $_ . "\n";
    $number=$number+1;
    #push(@numbers,($number));
    unshift(@numbers,($number));
    print("Array size is :" . @numbers . "\n");
    $i=$i+1;
    print("Individual Elements are:" . @numbers[i] . "\n");
    #pop(@numbers);
}

rhv:/var/cl_ip_down>./run.sh
Array size is :1
Individual Elements are:2
Array size is :2
Individual Elements are:3
Array size is :3
Individual Elements are:4

与流行音乐

#!/usr/bin/perl
@names = ("Abhijit","Royal Enfield","Google");
@numbers=();
$number=1;
$i=0;
foreach $name (@names) {
    #print $_ . "\n";
    $number=$number+1;
    #push(@numbers,($number));
    unshift(@numbers,($number));
    print("Array size is :" . @numbers . "\n");
    $i=$i+1;
    print("Individual Elements are:" . @numbers[i] . "\n");
    pop(@numbers);
}

rhv:/var/cl_ip_down>./run.sh
Array size is :1
Individual Elements are:2
Array size is :1
Individual Elements are:3
Array size is :1
Individual Elements are:4

【问题讨论】:

  • 您应该使用strictwarningsprint("Individual Elements are:" . @numbers[i] . "\n"); 中的 i 是什么?你为什么在那里使用数组切片?而且,您如何获得从该脚本显示的输出?哦,谁投票赞成这个问题?如果您想要的只是一个用于对问题进行投票的徽章,那么,对提出的问题投反对票也是一个有效的选择,您知道。

标签: perl


【解决方案1】:

您确实应该在代码中使用use strict;use warnings;。激活它们可以让您识别代码中的错误。

更改以下所有实例:

foreach $name (@names) -> for my $i (@names) 因为您不对@names 数组中的元素做任何事情。

@numbers[i] -> $numbers[$i] 因为这是您犯了一个常见的错误,即使用数组切片而不是引用数组元素。

这不是 C。每个“变量”前面都必须有一个印记($@%& 等)。 i 应该是 $i


至于pushshift的区别,文档解释:

perldoc -f push:

推送数组、列表

将 ARRAY 视为堆栈,并将 LIST 的值推送到 ARRAY 的 end。 ARRAY 的长度增加了 LIST 的长度。 ... 返回完成的“push”之后数组中的元素数。

perldoc -f unshift:

不移位数组,列表

与换档相反。或者与推动相反,这取决于您如何看待它。将列表添加到数组的front,并返回数组中新的元素个数。


以 ASCII 方式表示...

        +---------+           +-----------+        +---------+ 
<-----  | ITEM(S) |  ----->   | (@) ARRAY | <----- | ITEM(S) | ----->
 shift  +---------+  unshift  +-----------+  push  +---------+   pop
                              ^           ^
                              FRONT       END

【讨论】:

  • 很棒的图表。希望我可以 +2。
  • 注意:在“shift-reduce 解析”的上下文中,一个标记从包含(标记化的)输入字符串的数组的前面“移位”,并将它“推”到堆栈上.
【解决方案2】:

unshift 用于将一个或多个值添加到数组的开头

shift 相反。或 push 的反面,这取决于您如何看待它。

然后新值将成为数组中的第一个元素。

push 将元素添加到数组的end

ARRAY 视为一个堆栈,并将LIST 的值压入ARRAY 的末尾。

【讨论】:

  • 感谢思南的编辑。现在它的格式和解释肯定更好。
【解决方案3】:

这确实应该是一个评论,但是对于评论框来说太长了,所以在这里。

如果您想说明unshiftpush 之间的区别,以下内容就足够了:

#!/usr/bin/perl

use strict; use warnings;

my @x;

push @x, $_ for 1 .. 3;

my @y;

unshift @y, $_ for 1 .. 3;

print "\@x = @x\n\@y = @y\n";

输出:

@x = 1 2 3
@y = 3 2 1

注意use strict; 保护您免受许多程序员错误的影响,use warnings; 在您使用可疑值的构造时会警告您。在你的水平上,两者都不是可选的。

【讨论】:

    【解决方案4】:

    注意

    预分配的数组向数组的 0 端平衡(意味着列表远端的可用空间比列表的 0 元素之前的可用空间多)。这样做是故意使推送比取消移动更有效http://www.perlmonks.org/?node_id=17890

    虽然 列表 做得很好,因为 “Perl 的编码很巧妙,因为预期将列表用作队列(同上)”

    作为比较,在各种 JavaScript 引擎中 shift/unshift 对数组 seems to be significantly slower.

    【讨论】:

      【解决方案5】:

      我还没有看到这些方法在操作复杂性方面的实际作用,这有助于我进行概念化:从本质上讲,我相信它被称为“转移”,因为它实际上必须转移所有 n将数组中的元素设置为新索引,以便正确更新长度属性。

      push() 和 pop() 使用更简单的操作复杂性。无论您的数组中有多少个 n 值,或者您的 array.length,push 或 pop 将始终执行 1 次操作。它不需要处理索引,不需要迭代,它只需要执行一个操作,总是在堆栈的末尾,添加或删除一个值和索引。

      最重要的是,请注意在使用 push/pop 时,数组中的其他元素不会受到影响 - 它们是数组相同索引中的相同值。数组的长度也会自动正确更新为您在删除或添加值时所期望的。

      另一方面,shift() 和 unshift() 不仅可以添加或删除,还必须将数组中的所有其他元素实际“移位”到不同的索引中。这更复杂并且需要更多时间,因为操作量取决于 n、数组中元素的数量或 array.length。对于每一个更大的 n+1,它必须再执行 1 次操作才能将每个值移动到正确的索引中,从而正确地更新长度。

      否则,如果它在 shift() 之后没有执行 n 操作并移动其他元素,那么索引 0 处将没有元素,并且它不会改变数组的长度,对吗?我们希望数组的长度能够直观地更新,而 shift 和 unshift 必须执行更多操作才能完成。

      【讨论】:

        猜你喜欢
        • 2020-10-15
        • 1970-01-01
        • 2021-10-13
        • 1970-01-01
        • 2012-03-12
        • 2012-09-09
        • 2011-02-14
        • 2014-09-15
        相关资源
        最近更新 更多