2011-08-08 31 views
6

Tôi đã khá ngạc nhiên khi thấy rằng keys chức năng vui vẻ làm việc với mảng:

keys HASH 
keys ARRAY 
keys EXPR 

Trả về một danh sách bao gồm tất cả các phím của băm tên, hoặc chỉ số của một mảng. (Trong bối cảnh vô hướng, trả về số phím hoặc chỉ số.)

Có bất kỳ lợi ích trong việc sử dụng keys @array thay vì 0 .. $#array liên quan đến sử dụng bộ nhớ, tốc độ, vv, hoặc là những lý do cho chức năng này hơn của một nguồn gốc lịch sử?

Thấy keys @array nắm giữ lên đến $[ sửa đổi, tôi đoán đó là lịch sử:

$ perl -Mstrict -wE 'local $[=4; my @array="a".."z"; say join ",", keys @array;' 
Use of assignment to $[ is deprecated at -e line 1. 
4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29 

Trả lời

3

Các liên kết mà bạn cung cấp thực sự có một lý do quan trọng bạn có thể sử dụng/không sử dụng keys:

Như một tác dụng phụ, gọi phím() reset interator nội bộ của HASH hoặc ARRAY (xem mỗi). Đặc biệt, các phím gọi() trong ngữ cảnh void đặt lại trình lặp không có phí khác.

Điều đó sẽ gây ra each để đặt lại về đầu mảng. Sử dụng keyseach với mảng có thể quan trọng nếu chúng bao giờ hỗ trợ mảng thưa thớt như một kiểu dữ liệu thực.

Tất cả những gì đã nói, với rất nhiều cấu trúc ngôn ngữ nhận biết mảng như foreachjoin trong perl, tôi không thể nhớ lần cuối cùng tôi đã sử dụng 0..$#array.

+0

Đối với tôi, '0 .. $ # array' là một cấu trúc thuận tiện khi làm việc với' map', 'grep' và' sort': 'my @wantedIndices = grep {$ array [$ _] = ~/foo /} 0 .. $ # array; ' – Zaid

+0

Bạn có thể làm rõ ý nghĩa của một mảng thưa thớt không? – Zaid

+0

Một mảng thưa thớt về cơ bản là một băm với các phím số giữ lại thứ tự của các mục. Nếu bạn tạo một mảng với @a [1], @ [7] và @ [100_000_000] thì bạn sẽ nhận được một mảng lớn với tấn undef trong đó. 99% thời gian bạn có thể sử dụng một băm và được hạnh phúc với nó, nhưng đối với mảng thưa thớt lớn làm việc sắp xếp quan trọng hơn và hơn hút. – Mark

0

Vâng trong ví dụ của bạn, bạn đang đặt chúng trong một danh sách; Vì vậy, trong ngữ cảnh danh sách,

keys @array sẽ được thay thế bằng tất cả các thành phần của mảng trong khi 0 .. $#array sẽ thực hiện tương tự nhưng khi cắt mảng; Vì vậy, thay vào đó, bạn có thể đề cập đến $array[0 .. (some specific index)]

+0

Quibble: 'keys @ array' cung cấp cho bạn danh sách * chỉ mục * của mảng, chứ không phải các phần tử của nó. –

2

Tôi thực sự nghĩ bạn đã trả lời câu hỏi của riêng mình Vì vậy, từ một điểm tổng quát của xem (đặc biệt là cho việc sử dụng thư viện), nó được ưa thích hơn.

Phiên bản Perl tôi có (5.10.1) không hỗ trợ sử dụng keys với mảng, vì vậy không thể vì lý do lịch sử.

+1

Bạn nói đúng ... [nó đã được thêm vào trong Perl 5.12.0] (http://perldoc.perl.org/perl5120delta.html#each%2c-keys%2c-values-are-now-more-flexible). Có điều gì khác ngoài sự tuân thủ '$ [' không? Không phải mỗi ngày bạn tìm thấy '$ [' đang giữ một giá trị không mặc định ... – Zaid

+1

@Zaid: Hãy thử sử dụng nó với một mảng thưa thớt và xem liệu các khóa quay lại có còn thưa thớt hay không. (Tôi không có 5.12 để kiểm tra.) –

+0

Hãy làm rõ ý bạn là gì bởi một mảng thưa thớt. – Zaid

4

Đánh dấu một phần là đúng, tôi nghĩ vậy. Những gì anh ta mất tích là mỗi cái bây giờ làm việc trên một mảng, và, giống như mỗi cái có băm, mỗi mảng có mảng trả về hai mục trên mỗi cuộc gọi. Trường hợp each% hàm băm trả về khóa và giá trị, each @array cũng trả về khóa (chỉ mục) và giá trị.

while (my ($idx, $val) = each @array) 
{ 
    if ($idx > 0 && $array[$idx-1] eq $val) 
    { 
    print "Duplicate indexes: ", $idx-1, "/", $idx, "\n"; 
    } 
} 

Nhờ Zaid yêu cầu và jmcnamara để mang nó lên CB của perlmonks. Tôi đã không nhìn thấy điều này trước đây - Tôi thường xuyên lặp qua một mảng và muốn biết tôi đang ở đâu.Đây là waaaay tốt hơn so với thao tác thủ công một số biến số $i được tạo bên ngoài vòng lặp và tăng lên bên trong, như tôi mong đợi rằng continue, redo, v.v., sẽ tồn tại điều này tốt hơn. Vì vậy, bởi vì bây giờ chúng ta có thể sử dụng each trên mảng, chúng ta cần phải có thể đặt lại trình lặp đó, và do đó chúng ta có keys.

+0

Tôi đã không bỏ lỡ nó, tôi chỉ bỏ lỡ đề cập đến nó. :-) Tốt bắt và giải thích tốt! – Mark

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