2013-04-15 9 views
6

ho usatoPerl modo di iterare su 2 campi in parallelo

Use List::MoreUtils qw(each_array); 
my $it = each_array(@input_dump_arr, @created_dump_arr); 
while (my ($first, $second) = $it->()) { 
} 

Sarebbe questo lavoro in una configurazione di default Perl? Una domanda più ampia è ci sono delle linee guida per scrivere script perl "portatili"? Sono nuovo di Perl, sto solo cercando di capire se cpan è in realtà analogo a come le librerie di boost sono in C++.

risposta

4

È possibile utilizzare questa riscrittura più semplice della funzione each_arrayref del modulo. each_array è un involucro superfluo attorno a questa funzione che utilizza i prototipi per prendere i riferimenti agli array passati come parametri.

La sua funzionalità è identica alla versione del modulo, con la differenza che non esegue il controllo dei parametri che riceve e l'iteratore restituito non controlla che non abbia né parametri né 'index'.

use strict; 
use warnings; 

sub each_array { 

    my @copy = @_; 
    my $i; 
    my $max; 

    for (map scalar @$_, @copy) { 
    $max = $_ unless defined $max and $max > $_; 
    } 

    sub { 
    return $i if @_ and shift eq 'index'; 
    my $new_i = defined $i ? $i + 1 : 0; 
    return if $new_i >= $max; 
    $i = $new_i; 
    return map $_->[$i], @copy; 
    } 
} 

my @array1 = qw/ A B C /; 
my @array2 = qw/ D E F G /; 

my $iter = each_array(\@array1, \@array2); 

while (my @values = $iter->()) { 
    printf "%d: %s\n", $iter->('index'), join ', ', map $_ // 'undef', @values; 
} 

uscita

0: A, D 
1: B, E 
2: C, F 
3: undef, G 

Si potrebbe, naturalmente, semplicemente prendere il codice per each_arrayref dal modulo List::MoreUtils. È autonomo e garantisce la compatibilità con il codice esistente.

2

Ci sono moduli distribuiti direttamente con Perl stesso. Solitamente vengono chiamati "moduli principali". Puoi sempre usarli. List::Util è uno di questi, sebbene non lo sia List::MoreUtils.

Tuttavia, List::MoreUtils è un modulo disponibile su CPAN. CPAN è spesso considerato come "la libreria standard di Perl", simile a ciò che "la libreria standard" è per C++. La maggior parte delle persone pensa che sia giusto richiedere agli utenti della propria applicazione di installare alcuni moduli da CPAN, specialmente se sono moduli ben utilizzati.

List::MoreUtils è sicuramente un modulo ben utilizzato. È in circolazione da parecchio tempo. Tutte le principali distribuzioni Linux che conosco contengono versioni pacchettizzate di esso.

Quindi, se il vostro obiettivo non è quello di essere al 100% indipendenti di moduli non-core allora vi consiglio vivamente di continuare a utilizzare List::MoreUtils e la maggior parte degli altri moduli ad olio su CPAN. Sono il motivo per cui rocce di Perl.

Leggermente offtopic: devo ammettere che preferisco pairwise (anche da List::MoreUtils) per esattamente due array, poiché si comporta più come map. Per il tuo esempio:

use List::MoreUtils qw(pairwise); 
pairwise { do_stuff($a, $b) } @input_dump_arr, @created_dump_arr; 
+2

E se non si desidera richiedere 'List :: MoreUtils', si può ancora solo [copiare le parti che ti piacciono] (http://cpansearch.perl.org/src/RURBAN/List-MoreUtils-0.33 _007/lib/List/MoreUtils.pm) nella tua applicazione. – mob

+0

Wow grazie mob, Perl sta crescendo su di me: D – subramanian

+1

... se il codice viene distribuito con una licenza compatibile. – ikegami

5

Non è un modulo principale (che significa che non è in bundle con Perl), ma è uno relativamente comune. Non esiterei a usarlo.

se siete davvero paranoico potrebbe non essere disponibile, gli array assumendo sono della stessa dimensione, si può usare qualcosa di simile a quanto segue:

for my $i (0 .. $#array1) { 
    my $first = $array1[$i]; 
    my $second = $array2[$i]; 
} 

Tuttavia, per fortuna each_array() è implementato in puro perl, quindi puoi anche vedere la fonte di List/MoreUtils.pm e copiare e incollare le relative subroutine.