2011-07-15 5 views
5

いくつかのテストを満たす要素を見つけるための素早く簡単な方法はありますかは元の配列からこれらを削除しますか?一致するものと特定の条件に合致しないもの:どのようにして一致を除外しながら配列を通してgrepできますか?

例えば私は言い換える

@a = (1, 7, 6, 3, 8, 4); 
@b = grep_filter { $_ > 5 } @a; 

# now @b = (7, 6, 8) 
# and @a = (1, 3, 4) 

したい、私は2つのアレイにアレイを分割します。

+0

理由は? @ foreach(@a){if($ _> 5){push @b、$ _;} else {push @c、$ _;}}から2つの配列を作成するのは簡単で読みやすいです。 ')なぜこれを部分的に実行する必要がありますか?私は怠け者だから – mirod

+0

。 –

答えて

9

あなたのライブラリ、mangを知っていますか?

use List::MoreUtils qw(part); 
part { $_>5 } (1, 7, 6, 3, 8, 4) 

戻り

(
    [1, 3, 4], 
    [7, 6, 8], 
) 
+0

ニース、かなり私が探していたもの。 –

-1

これは必要なものですか?

@a = (1, 7, 6, 3, 8, 4); 
@b = grep_filter { $_ > 5 } @a; 
@a = grep_filter { $_ < 5 } @a; 

条件を否定して別のgrepを実行します。

+1

'<'は '>'の厳密な否定ではありません。 – Alnitak

+0

@Alnitak - あなたが正しいと言いましたが、私は言及しませんでしたが、コードが期待どおりに動作するように '<'ではなく '<='ではありません –

+0

@Tudor:なぜ論理エラーが予想よりも正しい<=? – pavel

8
my @a = (1, 7, 6, 3, 8, 4); 
my (@b, @c);  

push @{ $_ > 5 ? \@b : \@c }, $_ for @a; 
+0

+1これは、外部ライブラリを必要としない優れたソリューションであるためです。 –

3

ライブラリの使用は良いですが、完全を期すために、ここで問題に指定されている機能である:

sub grep_filter (&\@) { 
    my ($code, $src) = @_; 
    my ($i, @ret) = 0; 
    local *_; 
    while ($i < @$src) { 
     *_ = \$$src[$i]; 
     &$code 
      ? push @ret, splice @$src, $i, 1 
      : $i++ 
    } 
    @ret 
} 

my @a = (1, 7, 6, 3, 8, 4); 
my @b = grep_filter {$_ > 5} @a; 

say "@a"; # 1 3 4 
say "@b"; # 7 6 8 
関連する問題