3

我在 perl 中有一个数组,其中包含排序的非连续值。例如:1 2 3 5 7 11 13 15

我想删除所有在 and 之外的值,lower并在返回的选择中upper保留lowerand 。upper我这样做的方法看起来像这样(可能可以通过使用来改进slice):

my @culledArray;
for ( my $i = 0; $i < scalar(@array); $i++ ) { 
    if ( ( $array[$i] <= $_[1] ) and ( $array[$i] >= $_[0] ) ) { 
       push(@culledArray, $array[$i]);
    }
}

其中lowerupper分别包含在$_[0]$_[1]中。有没有内置的 perl 可以做到这一点?

4

3 回答 3

4

不知道任何内置的东西可以做到这一点(这是一个非常具体的要求),但你可以通过使用来节省一些打字grep

my @culledArray = grep {( $_ <= $_[1] ) and ( $_ >= $_[0] )} @array;

如果列表很长并且您不想复制它,那么查找开始和结束索引并使用切片可能会很有趣。

于 2012-05-27T19:48:33.027 回答
1

这很混乱,但我的单元测试通过了,所以它似乎有效。@array根据排序列表和的事实,获取下索引和上索引,$_[0] >= $_[1]然后创建@culledArrayfrom @array[$lower..$upper]

my @culledArray;
my $index = 0;
++$index until $array[$index] >= $_[0];
my $lowerIndex = $index;
while (($array[$index] <= $_[1]) and ($index < $#array)) { ++$index; }
my $upperIndex = $index;

@culledArray = @array[$lowerIndex .. $upperIndex];
return \@culledArray;

我很想知道这个与Mat 给出的答案的效率。我几乎可以肯定我不一定要遍历整个@array(因为我从 index of 遍历0直到找到$upperIndex. 我不确定grep链接答案中的方法是如何工作的,或者如何在上面perl实现切片@arrayto@culledArray代码,虽然。

于 2012-05-27T22:07:38.730 回答
0

看起来您可能正在使用百分位数或分位数?如果是这样,那么Statistics::Descriptive可能会有所帮助。

percentile方法返回该百分位数的值和索引,因此您可以使用如下代码

use strict;
use warnings;

use Statistics::Descriptive;

my @data = qw/ 1 2 3 5 7 11 13 15 /;

my $stat = Statistics::Descriptive::Full->new;
$stat->add_data(@data);
my ($d25, $i25) = $stat->percentile(25);
my ($d75, $i75) = $stat->percentile(75);

my @subset = ($stat->get_data)[$i25 .. $i75];

print "@subset\n";

输出

2 3 5 7 11
于 2012-05-28T13:48:27.173 回答