I have some perl code that looks something like this:
我有一些看起来像这样的perl代码:
my @array = map { rand } ( 1..100 );
my @matching = grep { $_ == $condition } @array;
@array = grep { $_ != $condition } @array;
This works ok, but what I would like to do is split the original array into two based on a single operation...I think I'm carrying out twice as many operations as strictly necessary.
这样做没问题,但我想做的是基于单个操作将原始数组拆分为两个...我认为我执行的操作数量是严格必要的两倍。
Help appreciated!! Thanks.
帮助赞赏!!谢谢。
3 个解决方案
#1
6
By far the easiest method is to iterate your array and push values to either of the two arrays depending on the condition, as in the below example.
到目前为止,最简单的方法是迭代数组并根据条件将值推送到两个数组中的任何一个,如下例所示。
for (@array) {
if ($_ % 2) {push @odd, $_}
else {push @even, $_}
}
If you'd like to modify the source array:
如果您想修改源数组:
for (my $i =0; $i < @array; ++$i) {
if ($array[$i] % 2) {
push @odd, splice (@array, $i--, 1);
}
}
Why didn't you recommend List::MoreUtils::part?
The module in question might not exists on the target system, which is always an annoying thing.
有问题的模块可能不存在于目标系统上,这总是令人讨厌的事情。
Also on the system I ran tests on I found that List::MoreUtils::part
was twice as slow as first snippet in this post, though with different implementations of part
it might be the opposite actually.
同样在系统上我运行测试我发现List :: MoreUtils :: part的速度是这篇文章中第一个片段的两倍,尽管有不同的部分实现,实际上可能是相反的。
#2
10
This is where part
from List::MoreUtils comes in handy.
这是List :: MoreUtils的一部分派上用场。
use List::MoreUtils qw'part';
my($even,$odd) = part { $_ % 2 } @array;
This works great if you want each element of input in exactly one array of the output.
如果您希望输入的每个元素恰好在输出的一个数组中,那么这很有用。
If you want to possibly put them in more than one of the arrays, you have to loop over them yourself.
The best way to do that is with a foreach
loop.
如果你想将它们放在多个数组中,你必须自己遍历它们。最好的方法是使用foreach循环。
my(@div2,@div3);
for my $elem (@array){
push @div2, $elem unless $elem % 2;
push @div3, $elem unless $elem % 3;
}
If there are a lot of similar checks you have to do, perhaps you should loop on what your testing against as-well.
如果你需要做很多类似的检查,也许你应该循环你的测试。
my %div;
for my $elem (@array){
for my $div (2,3,5,7,11,13){
push @{ $out{$div} }, $elem unless $elem % $div;
}
}
#3
3
I love the simplicity of List::MoreUtils
' part
function:
我喜欢List :: MoreUtils的部分功能的简单性:
sub part (&@) {
my ($code, @list) = @_;
my @parts;
push @{ $parts[ $code->($_) ] }, $_ foreach @list;
return @parts;
}
The resulting @parts
array is an array of arrayrefs. @$parts[0]
is the array of elements that returned false. @$parts[1]
returned true.
生成的@parts数组是一个arrayrefs数组。 @ $ parts [0]是返回false的元素数组。 @ $ parts [1]返回true。
#1
6
By far the easiest method is to iterate your array and push values to either of the two arrays depending on the condition, as in the below example.
到目前为止,最简单的方法是迭代数组并根据条件将值推送到两个数组中的任何一个,如下例所示。
for (@array) {
if ($_ % 2) {push @odd, $_}
else {push @even, $_}
}
If you'd like to modify the source array:
如果您想修改源数组:
for (my $i =0; $i < @array; ++$i) {
if ($array[$i] % 2) {
push @odd, splice (@array, $i--, 1);
}
}
Why didn't you recommend List::MoreUtils::part?
The module in question might not exists on the target system, which is always an annoying thing.
有问题的模块可能不存在于目标系统上,这总是令人讨厌的事情。
Also on the system I ran tests on I found that List::MoreUtils::part
was twice as slow as first snippet in this post, though with different implementations of part
it might be the opposite actually.
同样在系统上我运行测试我发现List :: MoreUtils :: part的速度是这篇文章中第一个片段的两倍,尽管有不同的部分实现,实际上可能是相反的。
#2
10
This is where part
from List::MoreUtils comes in handy.
这是List :: MoreUtils的一部分派上用场。
use List::MoreUtils qw'part';
my($even,$odd) = part { $_ % 2 } @array;
This works great if you want each element of input in exactly one array of the output.
如果您希望输入的每个元素恰好在输出的一个数组中,那么这很有用。
If you want to possibly put them in more than one of the arrays, you have to loop over them yourself.
The best way to do that is with a foreach
loop.
如果你想将它们放在多个数组中,你必须自己遍历它们。最好的方法是使用foreach循环。
my(@div2,@div3);
for my $elem (@array){
push @div2, $elem unless $elem % 2;
push @div3, $elem unless $elem % 3;
}
If there are a lot of similar checks you have to do, perhaps you should loop on what your testing against as-well.
如果你需要做很多类似的检查,也许你应该循环你的测试。
my %div;
for my $elem (@array){
for my $div (2,3,5,7,11,13){
push @{ $out{$div} }, $elem unless $elem % $div;
}
}
#3
3
I love the simplicity of List::MoreUtils
' part
function:
我喜欢List :: MoreUtils的部分功能的简单性:
sub part (&@) {
my ($code, @list) = @_;
my @parts;
push @{ $parts[ $code->($_) ] }, $_ foreach @list;
return @parts;
}
The resulting @parts
array is an array of arrayrefs. @$parts[0]
is the array of elements that returned false. @$parts[1]
returned true.
生成的@parts数组是一个arrayrefs数组。 @ $ parts [0]是返回false的元素数组。 @ $ parts [1]返回true。