2012-05-27 70 views
3

我在perl中有一個包含排序的非連續值的數組。例如:1 2 3 5 7 11 13 15剔除低位和高位,perl數組之外所有值的內置方法

我想刪除所有不lowerupper所有值,保持lowerupper在返回的選擇。我這樣做的方法是這樣的(或許可以通過使用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

不知道內置的,將做到這一點(這是一個相當具體的要求)任何東西,但你可以通過使用grep保存自己一些打字:

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

如果名單很長,你不想複製它,找到開始和結束索引並使用slice可能會很有趣。

1

這很混亂,但我的單元測試通過,所以它似乎工作。取下限和上限指標,基於這樣的事實,@array是一個排序列表和$_[0] >= $_[1],然後創建@culledArray@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; 

我很想知道這個效率VS the answer Mat gave。我幾乎可以肯定,我不一定遍歷整個@array(因爲我從0索引開始遍歷,直到找到$upperIndex。我不確定鏈接答案中的grep方法如何工作,或者perl如何實現切片的@array在上面的代碼@culledArray,雖然。

+0

如果你正在尋找的效率,具有大名單,二進制搜索(因爲數組排序)會比你提出什麼更有效。 'grep'遍歷整個數組,所以如果在上界(而且數組很大)上有很多元素,那麼它會比你的方法效率低。 – Mat

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 
相關問題