Qual è il modo migliore per attuare l'APL operatore di comprimere in Perl?

StackOverflow https://stackoverflow.com/questions/6823505

  •  26-10-2019
  •  | 
  •  

Domanda

A volte la mia APL familiarità mi dà idee algoritmiche per la soluzione dei problemi che ho re-implementare in una lingua che ho -. Perl, ad esempio

Così ho elaborato un file di testo per creare un vettore booleano che indica i campi utilizzati in un file delimitato, e ora voglio uscita gli indici di quei campi utilizzati, ei nomi dei campi utilizzati. In APL, vorrei utilizzare l'operatore comprimere il vettore di nomi dei campi, e sopra la virgola del numero di campi.

In Perl, ho fatto questo:

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

e

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

dove @UsedFields è un array contenente 0 per inutilizzato e 1 per campi usati.

  1. mi piace in realtà non usando la mappa con ?:() per comprimere simulare - c'è un modo migliore (il mio vero programma lo fa per la terza volta in cui la simulazione di una verticale o una riduzione sul file)

  2. Io non piace molto fare la mappa sopra gli indici per ottenere i risultati - c'è un modo migliore per calcolare questo? (Credo che un'ottimizzazione sarebbe quello di calcolare gli indici utilizzati, poi

    @UsedFieldNames = @FieldNames[@UsedIndexes];

È stato utile?

Soluzione

Altri modi:

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

Altri suggerimenti

L'approccio con grep o una mappa è quella giusta, ed è ciò che APL sarebbe stato utilizzando dietro le quinte. È possibile nascondere che in Perl anche con una subroutine:

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

Se si lavora con riferimenti ad array, avete alcune altre opzioni sintattiche, e in questo caso mi potrebbe scrivere come metodo scalare per l'applicazione infisso:

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top