2009-05-04 68 views
8

我需要創建一個文本文件(aptest.s),我可以用它來讀入另一個程序。我正在使用Perl,因爲我有一個很大的工作列表。我的代碼如下(它不提供所需的輸出 - 顯示在代碼和實際輸出之後)。任何幫助,將不勝感激。如何在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"; 
} 
} 

實際輸出

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 

所需的輸出

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 

回答

0

可以減少你的代碼和示例數據的大小,同時還重現錯誤?我無法立即看到實際產出和預期產出之間的差異。

有時,找到導致問題的最小代碼和數據集將使解決方案變得明顯。

更仔細地望了一下,只有一個輸出碼位是可變的:

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

你的錯誤很可能是在那裏。

+0

感謝大家的意見和建議。我已經使我的代碼更具可讀性,並感謝您的意見。 – Krishnan 2009-05-05 01:26:52

20

each_arrayList::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

是的。這可能是提問者需要的。 – 2009-05-04 23:24:10

4

認爲你想創建獨立的模塊,從與對應的元素從link2陣列相關聯的link陣列的每個元素?

但是你實際上輸出塊,每個組合linklink1

而是嘗試:

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

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

    ... 
} 
2

閱讀你的問題,這是很難說什麼你真的想知道。我相信Sinan Unur是正確的,並且你想要同時迭代兩個數組。正如他所說,List :: MoreUtils提供了非常方便的each_array()函數。

通過索引遍歷一個或多個數組也很簡單。

您可以生成一個索引列表,以便與正常for循環一起使用。這使用$#來獲取數組中最後一個值的索引。

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

或者您可以使用C風格for循環來生成您的索引。這使用了一個事實,即標量上下文中評估的數組返回元素的數量。

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

它也使用$#寫成:

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

在閱讀你的代碼,很明顯,你不熟悉Perl's quoting operators。有效地使用它們使您的腳本更易於編寫和閱讀。

以友好的精神,請允許我整理腳本:

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

感謝您的建議和代碼,使其更具可讀性和實用性。 – Krishnan 2009-05-05 01:28:49