如何删除数组的前五个元素?

25
@array = qw(one two three four five six seven eight);
<Some command here>
print @array;

2
Perl的数组处理非常深入。您不一定需要销毁数组才能对其进行操作。这只是一个例子 print join("\n", @array[5..$#array]), $/; - Ashley
补充Ashley所说的,除非我将其用作堆栈,否则我几乎从不需要从数组中删除元素。我猜想你可以改进你的代码,以便一开始就不添加这五个元素(如果它们是不必要的),或者像Ashley的示例中使用数组切片来获取你需要的元素而不破坏数组。 - converter42
2
一个非常简单的问题,有6个不同的工作答案,并且还在不断增加中。你一定会喜欢 Perl :) - cyber-guard
@Cyber-Guard 设计,听听! - Joel Berger
5个回答

60

以下是几种逐渐变得愚蠢的方法:

使用切片

@array = @array[ 5 .. $#array ];

使用splice函数:

splice @array, 0, 5;

使用 shift 函数:

shift @array for 1..5;

使用grep函数:

my $cnt = 0;
@array = grep { ++$cnt > 5 } @array;

使用map函数:

my $cnt = 0;
@array = map { ++$cnt < 5 ? ( ) : $_ } @array;

我相信比我更优秀的黑客们甚至能想出更傻的方法。 :)


我喜欢这个地图解决方案,它很整洁。 - cyber-guard
Map函数将遍历@array数组,并在遍历前五个元素后将这些元素重新赋值给该数组。使用三元条件和$cnt变量来评估是否已经遍历了这五个元素。 - cyber-guard
我还是不明白:如果 $cnt 小于 5,则列出,否则 $_ = 什么? - Literat
1
如果按照愚蠢程度递增的顺序排序,你的前两个示例是颠倒的。splice是执行此操作的方法,并且可以高效地执行此操作。自分配数组切片必须复制每个切片元素,最坏情况下需要 2*n 的空间来执行此操作。实际上,我可能会将其放在重复移位示例之下。 - Eric Strom
你能解释一下为什么第一个方法中有$#array这个变量吗?那个变量的使用真的让我很困惑。发生了什么事情,为什么井号没有注释掉东西? - Tom
显示剩余4条评论

14
你正在寻找内置函数splice
splice @array, 0, 5;

5

splice @array, 0, 5; 就可以了。


splice只能用于数字,无法用于数组中的字符串元素。 - Shan

4
作为对friedo答案的评论并展示酷炫的新声明“state”,以下是使用grep的实现,它类似于friedo的map。
#!/usr/bin/perl

use strict;
use warnings;

use feature 'state';

my @array = qw(one two three four five six seven eight);

my @new_array = grep {state $count; ++$count > 5} @array;

print "$_\n" for @new_array; 

-2

我刚意识到你只需要最后一个字符串,所以不需要循环

   my $_ = "@array"; s|(?:.*?\s){5}||;say;

顺便说一下,这可能是最低效的方法,只是为了好玩 :)

给那位投反对票的人:虽然这不算是做这件事情的‘最好’方法,但我的代码仍然能够工作。你应该明白我提供这个答案只是作为上面‘更加’正确的解决方案的另一种选择。 - cyber-guard
1
我没有点踩,但我猜想原因是如果@array的任何元素包含空格或者$" ne ' ',那么这个解决方案就会失效。 - Eric Strom
不错的发现。我会试图解决那个问题。 - cyber-guard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接