2009-05-04 14 views
8

Potrzebuję utworzyć plik tekstowy (aptest.s), którego mogę użyć do odczytu do innego programu. Używam Perla, ponieważ mam dużą listę do pracy. Mój kod jest następujący (który nie daje pożądanego wyniku - pokazany po kodzie i aktualnym wyjściu). Każda pomoc będzie doceniona.Jak mogę iterować na wielu listach w tym samym czasie w Perlu?

#!/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"; 
} 
} 

Rzeczywista wyjściowa:

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 

Pożądany Wyjście

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 

Odpowiedz

0

można zmniejszyć rozmiar swojego kodu i przykładowych danych jednocześnie odtwarzając błąd? Nie widzę od razu różnicy między faktycznym a oczekiwanym wynikiem.

Czasami znalezienie minimalnego zestawu kodu i danych, które powodują problem, sprawi, że rozwiązanie będzie oczywiste.

dokładniej Patrząc trochę, że jest tylko jeden bit kodu wyjściowego, który jest zmienny:

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"; 

Twój błąd jest prawdopodobne, aby tam być.

+0

Dziękuję wszystkim za komentarze i sugestie. Sprawiłem, że mój kod jest bardziej czytelny i doceniam twój wkład. – Krishnan

20

Zobacz each_array w 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

Tak. Prawdopodobnie to właśnie potrzebuje pytający. –

4

myślę starasz się stworzyć cztery oddzielne bloki, z każdego elementu z tablicy link związanego z odpowiedniego elementu z tablicy link2 ?

jednak jesteś rzeczywiście wyprowadzania szesnaście bloki, po jednym dla każdej połączeniu z link i link1.

Zamiast próbować:

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

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

    ... 
} 
2

Czytając twoje pytanie, trudno było powiedzieć, co naprawdę chciał wiedzieć. Wierzę, że Sinan Unur ma rację, i że chcesz iterować jednocześnie na dwóch tablicach. Jak mówi, List :: MoreUtils zapewnia bardzo przydatną funkcję each_array().

Łatwo jest również iterować przez jedną lub więcej tablic według indeksu.

Możesz wygenerować listę indeksów do użycia z normalną pętlą for. To używa $#, aby uzyskać indeks ostatniej wartości w tablicy.

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

Lub możesz użyć pętli w stylu C do generowania indeksów. Wykorzystuje to fakt, że tablica oceniana w kontekście skalarnym zwraca liczbę elementów.

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

To może być także napisane przy użyciu $#:

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

Po przeczytaniu kodu, było jasne, że nie jesteś zaznajomiony z Perl's quoting operators. Ich efektywne używanie znacznie ułatwia pisanie i czytanie skryptów.

W przyjaznym duchu, proszę pozwolić mi uporządkować swój skrypt:

#!/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

Dzięki za sugestie i kod, aby był bardziej czytelny i użyteczny. – Krishnan