用于获取数组中最大元素数的Perl习惯用法

时间:2010-07-27 18:16:28

标签: perl idioms

我想要除了阵列的前五个元素之外的所有元素,所以我愚蠢地做了:

@foo = @foo[ 0 .. 4 ];

衷心地称赞我自己的聪明才智。但是一旦@foo最终只有三个元素就会破坏,因为最后我最终得到了两个undef,而不是一个三元素数组。所以我把它改成了:

@foo = @foo > 5 ? @foo[ 0 .. 4 ] : @foo;

这有效,但有点难看。有没有更好的成语说“给我一切到阵列的前五个元素?”

4 个答案:

答案 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;