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

发布于 2024-09-12 08:25:19 字数 326 浏览 4 评论 0原文

我想砍掉数组中除了前五个元素之外的所有元素,所以我愚蠢地这么做了:

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

并由衷地称赞自己的聪明才智。但是一旦 @foo 最终只包含三个元素,这种情况就被打破了,因为最后我得到了两个 undef,而不是一个三元素数组。所以我把它改成了:

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

这可行,但有点难看。有没有更好的习惯用法来表达“给我数组前五个元素之前的所有内容?”

I wanted to chop off all but the first five elements of an array, so I stupidly did:

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

and heartily praised my own cleverness. But that broke once @foo ended up with only three elements, because then I ended up with two undefs on the end, instead of a three-element array. So I changed it to:

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

This works but is kinda ugly. Is there a better idiom for saying "give me everything up to the first five elements of the array?"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

疯狂的代价 2024-09-19 08:25:19

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

$#foo = 4 if $#foo > 4;

You can set the last index of an array to shorten or lengthen it. Like your code you'll need to check to make sure your not creating undef elements.

$#foo = 4 if $#foo > 4;
趁微风不噪 2024-09-19 08:25:19

如果您不关心突变(由自引用 lhs @foo = 引用 @foo 暗示),请使用两个参数splice(),请参阅 perldoc -f splice 了解更多信息信息。

拼接数组,偏移

从数组中删除由 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 @_;

如果您使用警告,我希望您必须检查长度(如 Axeman 的建议)或禁用噪音警告(splice() offset超出数组末尾):

{
  no warnings 'misc';
  splice @_, 5;
}

If you don't care about mutations (implied by the self-referential lhs @foo = something referencing @foo) use the two-argument splice(), see perldoc -f splice for more info.

splice ARRAY,OFFSET

Removes the elements designated by OFFSET and LENGTH from an array, and replaces them with the elements of LIST, if any. In list context, returns the elements removed from the array. In scalar context, returns the last element removed, or "undef" if no elements are removed. The array grows or shrinks as necessary. If OFFSET is negative then it starts that far from the end of the array. If LENGTH is omitted, removes everything from OFFSET onward. If LENGTH is negative, removes the elements from OFFSET onward except for -LENGTH elements at the end of the array. If both OFFSET and LENGTH are omitted, removes everything. If OFFSET is past the end of the array, perl issues a warning, and splices at the end of the array.

Then watch the effect:

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


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

If you're using warnings, and I hope you'll have to check for the length (as in Axeman's suggestion) or disable the noisy warning (splice() offset past end of array):

{
  no warnings 'misc';
  splice @_, 5;
}
冬天旳寂寞 2024-09-19 08:25:19

还有另一种方式:

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

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

Yet another way:

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

Unlike the other suggestion for splice, this doesn't trigger a warning; the 5 explicitly means "up to 5".

素年丶 2024-09-19 08:25:19

这不太优雅,但您可以这样表达:

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

通用的 min 函数可能看起来更好。

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

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

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

This isn't that graceful, but you can express it like this:

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

A generalized min function might look better.

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

But if you just want to get rid of everything else then you just need to splice off the rest:

splice( @foo, 5 ) if 5 < @foo;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文