2011-08-11 27 views
21

Nếu tôi có một bămTìm tên khóa trong băm chỉ với một khóa?

my %h = (
    secret => 1; 
); 

và tôi biết rằng chỉ là là một trong những quan trọng trong việc băm, nhưng tôi không biết những gì nó được gọi.

Đừng Sau đó tôi phải lặp qua đó băm

my $key; 
foreach my $i (keys %h) { 
    $key = $h{$i}; 
} 

Hoặc là có một cách tốt hơn để có được tên của khóa?

+0

Có một [giải pháp dễ dàng hơn nhiều] (http://stackoverflow.com/a/42809337/2932052) hơn tất cả các câu trả lời được đưa ra cho đến nay (bao gồm cả câu trả lời được chấp nhận). Nó cũng ngắn hơn và dễ hiểu và dễ nhớ. – Wolf

Trả lời

34

Một list slice nên làm điều đó

(keys %h)[0] 

keys trả về một danh sách, vì vậy chỉ cần trích xuất các phần tử đầu tiên của danh sách đó.

+7

Điều duy nhất để xem ra với phương pháp này là "trông giống như một chức năng" vấn đề. Để tránh điều này, bạn có thể cần '((keys% h) [0])' ví dụ 'perl -E 'my% h = (secret => 1); nói (phím% h) [0]; ''không thành công nhưng' perl -E' của tôi% h = (bí mật => 1); nói ((phím% h) [0]); ''hoạt động. Vấn đề là perl thấy 'say' và'() 'và phân tích cú pháp thành' (nói (phím% h)) [0] '. Vì vậy, hãy cẩn thận. –

+4

Không có mảng nào được trả về hoặc tham chiếu bị hủy đăng ký. Đã sửa lỗi thuật ngữ và thêm liên kết vào các tài liệu liên quan. – ikegami

6
my @keys = keys %h; 
my $key = $keys[0]; 
8

Tôi không tin rằng việc sử dụng hàm keys là không cần thiết.

my ($key) = %h; 

hoặc

my $key = (%h)[0]; 

Các băm bên trong dấu ngoặc sẽ được mở rộng đến một danh sách, sau đó chúng tôi chỉ có thể lấy phần tử đầu tiên của danh sách đó, đó là chìa khóa.

+1

Tôi đồng ý rằng điều này sẽ hoạt động. Tôi nghĩ rằng đó là một ví dụ về "quá thông minh-by-một nửa" cung cấp cho Perl một tên xấu. –

+0

Điều gì, bạn nghĩ điều này quá thông minh một nửa? – TLP

+0

Vậy 'my ($ x) =% h' quá thông minh? Các phím –

4

[ keys %h ]->[0] cũng sẽ thực hiện việc định hướng Joel đề cập trong nhận xét trước đó. Mã này có mùi giống như nó sẽ gây ra vấn đề mặc dù. Nếu thực sự chỉ có một cặp khóa/giá trị duy nhất, có thể có cách tốt hơn để xử lý dữ liệu.

Ít nhất, tôi muốn kiểm tra để đảm bảo kỳ vọng không bao giờ bị vi phạm âm thầm. Ví dụ. ‐

keys %h == 1 or die "ETOOMANYKEYS"; 
print [ keys %h ]->[0], $/; 
2
my $k = each %h; 

Tuy nhiên, bạn phải nhớ để thiết lập lại các iterator nếu bạn muốn sử dụng nó trên cùng bảng băm một lần nữa. Hoặc each sẽ làm điều đó, hoặc keys sẽ và nếu được sử dụng trong ngữ cảnh vô hướng, sẽ tránh tạo danh sách. Vì vậy, bạn có thể đặt lại với

scalar keys %h; 
# OR 
each %h;   # <- gets the undef 
my $k2 = each %h; # <- gets the first key 

Vì vậy, bạn có thể làm điều đó như thế này:

my $k = (scalar keys %h, each %h); 

Nhưng giả sử nó như đọc tin nhắn JSON và các công cụ mà bạn chỉ muốn đọc những gì trong băm một lần và ném nó đi, nó có lẽ là gọn gàng nhất. Tuy nhiên, nếu bạn muốn biến ngay lập tức, nó có thể dễ dàng hơn để làm điều này:

my ($k, $v) = each %$simple_JSON_structure; 
+1

trong khoảng trống cũng hoạt động (và sẽ hiệu quả hơn đối với mã băm được gắn) – ysth

+0

[Nhưng đừng quên đặt lại trình lặp bằng cách sử dụng các phím (% hash) sau đó hoặc tiếp theo sẽ thất bại.] (Https: // stackoverflow. com/posts/42809852/sửa đổi) – Wolf

12
my ($key) = keys %h; 

Khi bạn đang sử dụng danh sách bối cảnh trên cả hai mặt của toán tử gán, mục đầu tiên trong danh sách các phím được được gán cho $ key.

1

Hãy có một cái nhìn tại

my ($key) = %h; 

Hashes và mảng không phải là khác nhau như họ có vẻ. Cả hai đều liên quan chặt chẽ đến danh sách. Sử dụng danh sách là cách chúng được khởi tạo bình thường và => chủ yếu là bí danh cho , với sự khác biệt duy nhất là nó xử lý toán hạng trái của nó được trích dẫn hoàn toàn. Perl dừng chỉ khi bạn quên báo giá của toán hạng bên phải của nó, do đó, cả hai dòng sau sẽ được chấp nhận:

my %h = (a=>b=>c=>'d'); 
my @a = (a=>b=>c=>'d'); 

Vâng, bạn đã bao giờ thử điều này chưa?

my %h = ('key'); 

... hay này:

my @a = ('value'); 
my %h = @a; 

Các băm trên có thể nhìn một chút lạ, nhưng nó chỉ là một chìa khóa với giá trị undef.

Bởi vì đó là nhiều khả năng là bạn sẽ hỏi làm thế nào để truy cập giá trị duy nhất, tôi đề nghị sử dụng:

my ($key, $value) = %h; 

... hoặc thậm chí đơn giản hơn:

my ($key) = %h; 

Đó là những gì chúng tôi bắt đầu với .

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