2009-05-04 20 views
8

Ho bisogno di creare un file di testo (aptest.s) che posso usare per leggere in un altro programma. Sto usando Perl perché ho una grande lista da cui lavorare. Il mio codice è il seguente (che non fornisce l'output desiderato, mostrato dopo il codice e l'output effettivo). Qualsiasi aiuto sarebbe apprezzato.Come posso eseguire iterazioni su più elenchi contemporaneamente in Perl?

#!/usr/bin/perl -w 
chdir("D://projects//SW Model ODME"); 
@link = ("319-116264||319-118664","320-116380||320-116846","321-119118||321-119119","322-115298||322-119087"); 
@link1 = ("116264-319||118664-319","116380-320||116846-320","119118-321||119119-321","115298-322||119087-322"); 
open (FSAS, ">>aptest.s"); 
foreach $link (@link) { 
    foreach $link1 (@link1){ 
    print FSAS "other code \n"; 
    print FSAS "PATHLOAD SELECTLINK=(Link=".$link."), VOL[2]=MW[1] \n"; 
    print FSAS "PATHLOAD SELECTLINK=(Link=".$link1."), VOL[3]=MW[2] \n"; 
    print FSAS "other code \n"; 
} 
} 

effettiva uscita:

other output 
PATHLOAD SELECTLINK=(Link=319-116264||319-118664), VOL[2]=MW[1] 
PATHLOAD SELECTLINK=(Link=116264-319||118664-319), VOL[3]=MW[2] 
other output 

other output 
PATHLOAD SELECTLINK=(Link=**319-116264||319-118664**), VOL[2]=MW[1] 
PATHLOAD SELECTLINK=(Link=**116380-320||116846-320**),  VOL[3]=MW[2] 
other output 

desiderata uscita

other output 
PATHLOAD SELECTLINK=(Link=319-116264||319-118664), VOL[2]=MW[1] 
PATHLOAD SELECTLINK=(Link=116264-319||118664-319), VOL[3]=MW[2] 
other output 

other output 
PATHLOAD SELECTLINK=(Link=**320-116380||320-116846**), VOL[2]=MW[1] 
PATHLOAD SELECTLINK=(Link=**116380-320||116846-320**), VOL[3]=MW[2] 
other output 

risposta

0

Si può ridurre la dimensione dei dati di codice e di esempio, pur riproducendo l'errore? Non riesco a vedere immediatamente la differenza tra l'output effettivo e quello atteso.

A volte, trovare un set minimo di codice e dati che causa un problema renderà la soluzione ovvia.

Guardando un po 'più attentamente, c'è solo un po' di codice di uscita che è variabile:

print FSAS "PATHLOAD PATH=TIME, MW[1]=MI.1.1, SELECTLINK=(Link=".$link."), VOL[2]=MW[1] \n"; 
print FSAS "PATHLOAD PATH=TIME, MW[2]=MI.1.1, SELECTLINK=(Link=".$link1."), VOL[3]=MW[2] \n"; 

il bug è probabile che sia lì.

+0

Grazie a tutti per i vostri commenti e suggerimenti. Ho reso il mio codice più leggibile e apprezzo il tuo contributo. – Krishnan

20

Vedi each_array in List::MoreUtils:

#!/usr/bin/perl 

use strict; 
use warnings; 

use List::MoreUtils qw(each_array); 

my @x = qw(A B C D E F); 
my @y = (10, 11, 12, 13, 14, 15); 

my $it = each_array(@x, @y); 
while (my ($x, $y) = $it->()) { 
    print "$x = $y\n"; 
} 
__END__ 
+0

Sì. Questo è probabilmente ciò di cui l'interrogante ha bisogno. –

4

io penso si sta cercando di creare quattro blocchi separati, con ogni elemento dal link matrice associata al corrispondente elemento dalla matrice link2 ?

Tuttavia si sta effettivamente l'output sedici blocchi, uno per ogni combinazione di link e link1.

cercare invece:

foreach $i (0 .. $#link) { 

    $link = $link[$i]; 
    $link1 = $link1[$i]; 

    ... 
} 
2

Leggendo la tua domanda, era difficile dire che cosa si voleva davvero conoscere. Credo che Sinan Unur sia corretto e che tu voglia scorrere simultaneamente su due array. Come dice, List :: MoreUtils fornisce la pratica funzione each_array().

È anche semplice iterare su uno o più array per indice.

È possibile generare un elenco di indici da utilizzare con un ciclo normale. Questo utilizza $# per ottenere l'indice dell'ultimo valore dell'array.

for (0..$#array) { ... } 

Oppure è possibile utilizzare uno stile C per il ciclo per generare gli indici. Questo utilizza il fatto che un array valutato in contesto scalare restituisce il numero di elementi.

for (my $i=0; $i<@array; $i++) { ... } 

Potrebbe anche essere scritta utilizzando $#:

for (my $i=0; $i<=$#array; $i++) { ... } 

Dopo aver letto il codice, era chiaro che non si ha familiarità con Perl's quoting operators. Usarli efficacemente rende gli script molto più facili da scrivere e leggere.

In uno spirito amichevole, mi permetta di riordinare lo script:

#!/usr/bin/perl 

# Always: 
use strict; 
use warnings; 

#my $TARGET_DIR = 'D://projects//SW Model ODME'; 
my $TARGET_DIR = '.'; 

my $TARGET_FILE = 'aptest.s'; 

# Using qw() makes long lists of 
# literals easier to type and read. 
# Consider finding better names than link and link1. 
# Something that describes the relationship between 
# the two arrays. 
my @link = qw(
    319-116264||319-118664 
    320-116380||320-116846 
    321-119118||321-119119 
    322-115298||322-119087 
); 

my @link1 = qw(
    116264-319||118664-319 
    116380-320||116846-320 
    119118-321||119119-321 
    115298-322||119087-322 
); 

# check the results of chdir. 
chdir($TARGET_DIR) 
    or die "Unable to enter $TARGET_DIR - $!\n"; 

# Use a lexical filehandle. 
# Use 3 arg open 
# Check the results of open - you need to know if it fails. 
open (my $fsas, '>>', $TARGET_FILE) 
    or die "Unable to open $TARGET_FILE - $!\n"; 

# Verify that the link arrays are both sized appropriately. 
die "Link arrays are not the same size." 
    unless @link == @link1; 

# Loop over the indexes of the array. 
# For very (very) large arrays it is 
# more efficient to use a C-style for loop: 
# for(my $i = 0; $i < @link; $i++) { 
foreach my $i (0..$#link) { 
    my $link = $link[$i]; 
    my $link1 = $link1[$i]; 

    print $fsas Get_Link_Text($link, $link1); 
} 

# Broke out your formatting code into a routine for readability. 
# Used a heredoc to make the formatting easier to read. 
# Also, took advantage of variable interpolation in the heredoc to further 
# improve readability. 
# I preserved the whitespace at the end of lines, is it really necessary? 
sub Get_Link_Text { 
    my $link = shift; 
    my $link1 = shift; 

    return <<"--END_TEXT--"; 
RUN PGM=HWYLOAD 
MATI=daily_trucks.MAT 
NETI=FAF_Network_V11.net 
NETO=MiamiDade.NET 
PARAMETERS MAXITERS=1, GAP=0.001, COMBINE=EQUI 
FUNCTION { 
TC[1] = T0*(1+0.15*(V/100)^(4))}  
FUNCTION V = (VOL[1]) 
PHASE=ILOOP 
PATHLOAD PATH=TIME, MW[1]=MI.1.1, SELECTLINK=(Link=$link), VOL[2]=MW[1] 
PATHLOAD PATH=TIME, MW[2]=MI.1.1, SELECTLINK=(Link=$link1), VOL[3]=MW[2] 
ENDPHASE 
ENDRUN 


--END_TEXT-- 
} 
+0

Grazie per i suggerimenti e il codice per renderlo più leggibile e utile. – Krishnan

Problemi correlati