我想要除了阵列的前五个元素之外的所有元素,所以我愚蠢地做了:
@foo = @foo[ 0 .. 4 ];
衷心地称赞我自己的聪明才智。但是一旦@foo
最终只有三个元素就会破坏,因为最后我最终得到了两个undef
,而不是一个三元素数组。所以我把它改成了:
@foo = @foo > 5 ? @foo[ 0 .. 4 ] : @foo;
这有效,但有点难看。有没有更好的成语说“给我一切到阵列的前五个元素?”
答案 0 :(得分:8)
您可以设置数组的最后一个索引来缩短或延长它。与您的代码一样,您需要检查以确保不创建undef元素。
$#foo = 4 if $#foo > 4;
答案 1 :(得分:6)
如果你不关心突变(由自我引用lhs暗示 @foo
=引用@foo
的东西),请使用双参数splice()
,有关详细信息,请参阅perldoc -f splice。
拼接ARRAY,OFFSET
从数组中删除OFFSET 和LENGTH指定的元素,并将其替换为LIST的元素(如果有)。 在列表上下文中,返回从中删除的元素数组。在标量上下文中,返回删除的最后一个元素,如果没有删除元素,则返回“undef”。阵列会根据需要增大或缩小。如果OFFSET是负数,则它从数组的末尾开始。如果省略LENGTH,则从OFFSET开始删除所有内容。 如果LENGTH为负数,则从OFFSET向前移除元素,除了数组末尾的-LENGTH元素。 如果省略OFFSET和LENGTH,则删除所有内容。如果OFFSET超过了数组的末尾,则perl会发出警告,并在数组末尾进行拼接。
然后看效果:
@_ = 1..10;
splice @_, 5;
say for @_;
@_ = 1..3;
splice @_, 5;
say for @_;
如果你正在使用warnings
,我希望你必须检查长度(如Axeman的建议)或禁用噪音警告( splice()偏移超过数组的结尾< / em>的):
{
no warnings 'misc';
splice @_, 5;
}
答案 2 :(得分:6)
另一种方式:
@foo = splice(@foo, 0, 5);
与拼接的其他建议不同,这不会触发警告; 5明确表示“最多5”。
答案 3 :(得分:1)
这不是那么优雅,但你可以这样表达:
@foo[ 0..( $#foo > 4 ? 4 : $#foo ) ];
广义min
函数可能看起来更好。
use List::Util qw<min>;
@foo[ 0..min( $#foo, 4 ) ];
但是如果你只是想摆脱其他一切,那么你只需要splice
来完成剩下的工作:
splice( @foo, 5 ) if 5 < @foo;