代码之家  ›  专栏  ›  技术社区  ›  friedo

Perl习语,用于获取数组中最大数量的元素

  •  6
  • friedo  · 技术社区  · 14 年前

    我想砍掉一个数组的前五个元素以外的所有元素,所以我愚蠢地做到了:

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

    并衷心赞扬我自己的聪明。但那只破了一次 @foo 最后只有三个元素,因为我最后只有两个元素 undef s位于末尾,而不是三元素数组。所以我把它改成:

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

    这行得通,但有点难看。有没有更好的成语说“把数组的前五个元素都给我”?

    4 回复  |  直到 14 年前
        1
  •  8
  •   Ven'Tatsu    14 年前

    可以将数组的最后一个索引设置为缩短或延长该索引。像您的代码一样,您需要检查以确保不创建undef元素。

    $#foo = 4 if $#foo > 4;
    
        2
  •  6
  •   Evan Carroll    14 年前

    如果你不关心突变(由自我参照的lhs所暗示) @foo =引用的内容 @福 )使用两个参数 splice() perldoc -f splice 更多信息。

    拼接阵列,偏移

    删除由偏移指定的元素 以及数组的长度,并将其替换为list元素(如果有)。 在列表上下文中,返回从数组中删除的元素。在标量上下文中,返回最后删除的元素,如果没有删除任何元素,则返回“undef”。阵列根据需要增大或缩小。如果偏移量为负,则它将从距离数组末尾很远的位置开始。如果省略了长度,则从偏移开始删除所有内容。 如果长度为负,则从偏移开始删除元素,但数组末尾的长度元素除外。 如果同时忽略偏移和长度,则删除所有内容。如果偏移量超过了数组的末尾,Perl将发出警告,并在数组的末尾进行拼接。

    然后观察效果:

    @_ = 1..10;
    splice @_, 5;
    say for @_;
    
    
    @_ = 1..3;
    splice @_, 5;
    say for @_;
    

    如果你在用 warnings 我希望你必须检查长度(如阿克塞曼的建议),或者禁用噪音警告。( splice()超过数组结尾的偏移量 ):

    {
      no warnings 'misc';
      splice @_, 5;
    }
    
        3
  •  6
  •   ysth    14 年前

    另一种方式:

    @foo = splice(@foo, 0, 5);
    

    与其他拼接建议不同,这不会触发警告;5明确表示“最多5个”。

        4
  •  1
  •   Axeman maxelost    14 年前

    这不是那么优雅,但你可以这样表达:

    @foo[ 0..( $#foo > 4 ? 4 : $#foo ) ];
    

    广义的 min 函数可能看起来更好。

    use List::Util qw<min>;    
    @foo[ 0..min( $#foo, 4 ) ];
    

    但如果你只是想摆脱其他一切,那么你只需要 splice 其余的:

    splice( @foo, 5 ) if 5 < @foo;