2011-07-25 9 views
2

私のAPLに精通していると、問題解決のためのアルゴリズム的なアイデアが得られることがあります。たとえば、Perlなどの言語で実装し直すことができます。PerlでAPL圧縮演算子を実装する最良の方法は何ですか?

私は、区切られたファイルで使用されているフィールドを示すブールベクトルを作成するためにテキストファイルを処理しました。そして、使用されたフィールドのインデックスと使用されるフィールドの名前を出力します。 APLでは、フィールド名のベクトルとフィールド数のiotaに渡ってcompress演算子を使用します。

は、Perlで、私はこれをした:

my @UsedFieldNames = map { $UsedFields[$_] ? $FieldNames[$_] :() } 0 .. $#UsedFields; 

@UsedFieldsが使用されるフィールドのために未使用と1 0を含む配列である

say join " ", map { $UsedFields[$_] ? $) :() } 0 .. $#UsedFields; 

  1. 私は実際に圧縮をシミュレートするため?:()でマップを使用して好きではない - より良い方法は、(私の本当のプログラムはそれをファイルの上に垂直または縮小をシミュレートする三回目を行います)がありますか?

  2. 結果を得るためにインデックス上で地図を作成するのは本当に好きではありません - それを計算する良い方法はありますか? (私は1つの最適化は、最初に使用したインデックスを計算するのだろうと思い、その後、

    @UsedFieldNames = @FieldNames[@UsedIndexes];

答えて

3

その他の方法:grepのか、マップと

my @UsedFieldNames = map { ($FieldNames[$_]) x !!$UsedFields[$_] } 0..$#UsedFields; 
my @UsedFieldNames = @FieldNames[ grep $UsedFields[$_], 0..$#UsedFields ]; 
+0

私はgrepのが好き、私は見つけられません。最初の選択肢は '?:()'に勝る魅力的な改良です。私は覚えておくべき一般的なルールを見ています。 'map {x($ _)? $ _:()} y'は 'grep x($ _)、y'と置き換えることができます – NetMage

+0

データの一部がハッシュであった場合、それは他に何をしているかによって決まります。 – ysth

+0

+1この素敵なスプライス –

4

アプローチが正しいものである、とありますどのようなAPLがバックグラウンドで使用されていたのでしょうか?サブルーチンでもそれをPerlで隠すことができます:

sub compress (\@\@) { 
    @{$_[0]}[ grep $_[1][$_] => 0 .. $#{$_[1]} ] 
#or use: 
# map {$_[1][$_] ? $_[0][$_] :()} 0 .. $#{$_[0]} 
} 

my @source = qw(one two three four); 
my @ok  = qw(0 1 0  1 ); 

my @new = compress @source, @ok; 

say "@new"; # two four 

あなたは配列参照を使用している場合、あなたはいくつかの他の構文オプションがあり、この場合には、私は中置アプリケーションのためのスカラー方法としてそれを書くかもしれない:

my $compress = sub { 
    my $src = shift; 
    my $ok = @_ == 1 && ref $_[0] eq 'ARRAY' ? shift : \@_; 
    wantarray ?   @$src[ grep $$ok[$_] => 0 .. $#$ok ] 
       : sub{\@_}->(@$src[ grep $$ok[$_] => 0 .. $#$ok ]) 
}; 

my $source = [qw(one two three four)]; 
my $ok  = [qw(1 0 1  0 )]; 

my $new = $source->$compress($ok); 

say "@$new"; # one three 
say join ' ' => $source->$compress(0, 1, 1, 0); # two three 
関連する問題