2010-03-24 30 views
5

Đây là lần đầu tiên tôi đã thao tác băm và mảng theo cách này - và nó đang hoạt động. Về cơ bản, cho mỗi khóa có nhiều giá trị mà tôi muốn ghi lại và sau đó in ra dưới dạng "khóa -> giá trị -> giá trị -> val ..."Đây có phải là cách chính xác để xây dựng một hàm băm Perl sử dụng mảng không?

Mã của tôi như sau. Tôi ngạc nhiên rằng nó hoạt động, vì vậy lo ngại rằng nó hoạt động "do nhầm lẫn". Đây có phải là cách chính xác để hoàn thành nhiệm vụ này không, hoặc có phương pháp hiệu quả hơn hay phù hợp hơn không?

while ($source =~ m/(regex)/g) { #Get all key names from source 
    $listkey = $1; #Set current list key to the current regex result. 
    $list{$listkey} = ++$i unless $list{$listkey}; #Add the key to the hash unless it already exists. 
    $list{$listkey} = [] unless exists $list{$listkey}; #Add an array for the hash unless the hash already exists. 
    while ($loopcount==0) { 
      if ($ifcount==0) { 
        $listvalue=result_of_some_function_using_list_key; #Get the first list value by using the list key. 
        $ifcount++; #Increment so we only get the first list value once. 
      } else { 
        $listvalue=result_of_some_function_using_list_value; #Update the list value by using the last list value. 
      } 
      if ($listvalue) { #If the function returned a value... 
        push @{$list{$listkey}}, $listvalue; #...then add the value to the hash array for the key. 
      } else { #There are no more values and we need a new key. 
        $listkey=0; #Reset variable. 
        $listvalue=0; #Reset variable. 
        $loopcount++; #Increment loop counter to exit loop. 
      } 
    } 
$ifcount=0; #Reset count variable so the next listvalue can be generated from the new key. 
    $loopcount=0; #Reset count variable so another loop can begin for a new key. 
} 
foreach $listkey (keys %list) { #For each key in the hash. 
    print "$listkey --> "; #Print the key. 
    @values = @{$list{$listkey}}; #Reference the arrays of the hash. 
    print join ' --> ', @values; #Print the values. 
    print "\n"; #Print new line. 
} 
+7

Bạn thực sự phải ở trong 'sử dụng nghiêm ngặt; sử dụng cảnh báo; 'mode – Zaid

+0

Ouch, đã tạo ra một danh sách cảnh báo độc ác. Tôi sẽ phải trải qua chúng. – Structure

+4

Tôi hy vọng rằng mã thực sự không có nhiều ý kiến ​​này. –

Trả lời

2

Mã sau đây không giống như mã của bạn, mà không cần các bước không cần thiết.

while ($source =~ m/(regex)/g) { # Get all key names from source 
    $listkey = $1;   # Grab current regex result. 
    $listvalue = result_of_some_function_using_list_key; 
    while ($listvalue) { 
     push @{$list{$listkey}}, $listvalue; 
     $listvalue = result_of_some_function_using_list_value; 
    } 
    $listkey = 0;    # Reset variable. 
    $domain = 0;     # Reset variable. 
} 

Tuy nhiên, như những người khác đã nhận xét, các biến toàn cục nên tránh trong hầu hết các trường hợp. Thay vào đó, giá trị danh sách và khóa danh sách phải được lexically scoped với my(), và các chức năng để tạo ra các giá trị danh sách phải mất một hoặc nhiều tham số (tên miền, danh sách khóa và/hoặc giá trị danh sách) làm đầu vào.

Các dòng

$list{$listkey} = ++$i unless $list{$listkey}; 
$list{$listkey} = [] unless exists $list{$listkey}; 

trong mã gốc của bạn không cần thiết, nó là đủ với push @{ $list{$key} }, $value để khởi tạo một mục nhập.

+0

Cảm ơn, tôi có một sự hiểu biết tốt hơn về nơi tôi đã đi sai sau khi giải thích ngắn gọn. – Structure

1

Không! Nếu điều này hoạt động, chắc chắn là "do nhầm lẫn". Nhưng rõ ràng đây không phải là mã thực sự của bạn và bạn đã thêm nhiều lỗi trong "dịch" nó thành một ví dụ, vì vậy thật khó để đánh giá chính xác ý định là gì, nhưng đi từ khung chương trình của bạn, có vẻ như giống như là:

my %result; 

while ($source =~ m/(regex)/g) { 
    my $key = $1; 
    my $value = mangle($key); 
    while ($value) { 
    push @{ $results{$key} }, $value; 
    $value = frob($value); 
    } 
} 

và không còn nữa. Nỗ lực của bạn để khởi tạo băm không làm những gì bạn nghĩ là (và không cần thiết), vòng lặp while của bạn như được viết không phải là một ý tưởng hay cả, và không phải tất cả các biến toàn cầu.

2

Mã ở trên có nhiều bước không cần thiết. Perl là một ngôn ngữ rất biểu cảm và cho phép logic như thế này được thể hiện rất đơn giản:

# uncomment for some sample data 
# sub function {"@_" !~ /^\[{3}/ and "[@_]"} 
# my $source = 'one two three'; 

my %list; 
while ($source =~ m/(\S+)/g) { 
    my $key = $1; 
    my $value = function($key); 

    while ($value) { 
     push @{ $list{$key} }, $value; 
     $value = function($value) 
    } 
} 

for my $key (keys %list) { 
    print join(' --> ' => $key, @{$list{$key}}), "\n"; 
} 
+0

đã đồng ý. nói chung, trong Perl, bạn chỉ nên xem các chỉ số vòng lặp (vòng lặp kiểu C cho ($ i = 0 ... 'C) hoặc các quầy trong trường hợp bạn thực sự cần phải làm điều gì đó với các giá trị đó. một nguồn tốt của lỗi vụng về tại chỗ – plusplus

Các vấn đề liên quan