2009-05-04 6 views
8

Tôi cần tạo một tệp văn bản (aptest.s) mà Ican sử dụng để đọc vào một chương trình khác. Tôi đang sử dụng Perl vì tôi có một danh sách lớn để làm việc. Mã của tôi là như sau (mà không cung cấp cho đầu ra mong muốn - hiển thị sau mã và đầu ra thực tế). Bất kỳ trợ giúp sẽ được đánh giá cao.Làm thế nào tôi có thể lặp qua nhiều danh sách cùng một lúc trong 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"; 
} 
} 

Output thực tế:

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 

mong muốn 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 

Trả lời

0

Bạn có thể giảm kích thước của mã và ví dụ dữ liệu của bạn trong khi vẫn tái tạo lỗi? Tôi không thể thấy ngay sự khác biệt giữa sản lượng thực tế và dự kiến.

Đôi khi, việc tìm một bộ mã và dữ liệu tối thiểu gây ra sự cố sẽ làm cho giải pháp hiển nhiên.

Nhìn một chút cẩn thận hơn, chỉ có một chút mã đầu ra có thể thay đổi:

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

lỗi của bạn có thể sẽ có mặt ở đó.

+0

Nhờ mọi người cho ý kiến ​​và đề xuất của bạn. Tôi đã làm cho mã của tôi dễ đọc hơn và đánh giá cao đầu vào của bạn. – Krishnan

20

Xem each_array trong 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

Có. Đó có lẽ là điều người hỏi cần. –

4

tôi nghĩ bạn đang cố gắng để tạo ra Bốn khối riêng biệt, với mỗi phần tử từ link mảng kết hợp với các yếu tố tương ứng từ mảng link2 ?

Tuy nhiên bạn đang thực sự xuất ra mười sáu khối, một cho mỗi kết hợp của linklink1.

Thay vì cố gắng:

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

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

    ... 
} 
2

Đọc câu hỏi của bạn, nó rất khó để nói những gì bạn thực sự muốn biết. Tôi tin rằng Sinan Unur là chính xác, và bạn muốn lặp lại đồng thời qua hai mảng. Như ông nói, Danh sách :: MoreUtils cung cấp chức năng rất tiện dụng each_array().

Cũng đơn giản để lặp qua một hoặc nhiều mảng theo chỉ mục.

Bạn có thể tạo danh sách các chỉ mục để sử dụng với vòng lặp bình thường. Điều này sử dụng $# để lấy chỉ mục của giá trị cuối cùng trong mảng.

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

Hoặc bạn có thể sử dụng kiểu C cho vòng lặp để tạo chỉ mục của mình. Điều này sử dụng thực tế là một mảng được đánh giá trong ngữ cảnh vô hướng trả về số lượng các phần tử.

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

Nó cũng có thể được viết bằng $#:

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

Khi đọc mã của bạn, nó là rõ ràng rằng bạn không quen thuộc với Perl's quoting operators. Sử dụng chúng một cách hiệu quả làm cho kịch bản của bạn dễ dàng hơn để viết và đọc.

Trong một tinh thần thân thiện, xin vui lòng cho phép tôi dọn kịch bản của bạn:

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

Cảm ơn các đề xuất và mã để làm cho nó dễ đọc hơn và hữu ích hơn. – Krishnan