2011-04-24 45 views
13

Có băm tương đương cho map không?bản đồ cho băm trong Perl

my %new_hash = hash_map { new_key($a) => new_val($b) } %hash; 

Tôi biết rằng tôi có thể lặp qua các phím.

Trả lời

15

List::Pairwise tuyên bố để triển khai chính xác cú pháp đó - xem mapp, grepp. Tôi đã không sử dụng nó mặc dù.

Ngoài ra, bạn có thể làm điều đó như

%new_hash = map { new_key($_) => new_value($hash{$_}) } keys %hash; 

mà tôi thừa nhận trông vụng về nếu %hash thực sự là một $deeply->{buried}->{hash}. Tôi thích sử dụng $temp = ...; map {...} keys %$temp trong những trường hợp như vậy.

+1

'Danh sách :: từng đôi :: tác phẩm mapp' tuyệt quá. – Tim

5

Bạn có thể sử dụng bản đồ như thế này:

my $i = 0; 
my %new_hash = map { $i ^= 1 ? new_key($_) : new_val($_) } %hash; 
+0

Xin lỗi, ví dụ của tôi chỉ là một trường hợp đặc biệt. Tôi muốn 'new_key' và' new_val' là các hàm của cả khóa và giá trị. (Điều này trả lời câu hỏi tôi đã hỏi, mặc dù.) – Tim

3

Bạn có thể sử dụng mapn từ mô-đun của tôi List::Gen để làm điều này:

use List::Gen 'mapn'; 

my %new_hash = mapn {new_key($_[0]) => new_value($_[1])} 2 => %old_hash; 

mapn cũng giống như bản đồ, ngoại trừ nó phải mất một đối số bổ sung, số lượng các yếu tố để đi bộ danh sách theo. Bên trong khối, mảng @_ được đặt thành lát hiện tại.

+0

Cảm ơn, đó là tổng quát hơn. – Tim

5

Tôi thực sự không thể thấy những gì bạn đang cố gắng làm ở đây. “Tương đương băm cho map” có nghĩa là gì? Bạn có thể sử dụng map trên một hàm băm tốt. Nếu bạn muốn các phím, chỉ cần sử dụng keys; ví dụ như"

@msglist = map { "value of $_ is $hash{$_}" } keys %hash  

mặc dù thường

nói "giá trị của $ _ là $ băm {$ _}" chìa khóa% băm;.

là tốt

Nếu bạn muốn cả hai , sau đó sử dụng toàn bộ hàm băm.

Để gán, có gì sai với %new_hash = %old_hash?

Bạn có vấn đề sao chép sâu? Sau đó, sử dụng Storable::dclone.

Bạn có muốn cả khóa và giá trị có sẵn trong quá trình đóng cửa cùng một lúc không? Sau đó thực hiện một loạt các cặp với bản đồ đầu tiên:

@pairlist = map { [ $_ => $hash{$_} ] } keys %hash 

tôi cần phải xem ví dụ về những gì bạn muốn làm với điều này, nhưng cho đến nay tôi có thể thấy không lý do để sử dụng một số mô-đun lớn tuổi thay vì Perl cơ bản.

+0

Tôi đang tìm kiếm một giải pháp thay thế thanh lịch hơn để sử dụng các phím '. 'List :: Pairwise' và' List :: Gen', như đã gợi ý, cung cấp như vậy. Chưa bao giờ có bất kỳ rắc rối chuyển nhượng nào, vì vậy đó có thể là một sự hiểu lầm. Như khi nó có giá trị nó bằng cách sử dụng một mô-đun để đơn giản hóa chương trình, tôi cho rằng đó là một vấn đề của hương vị. – Tim

+0

@Tim: Danh sách :: Gen có vẻ hơi thú vị, nhưng tôi không thể cho cuộc sống của tôi nghĩ tại sao mọi người sẽ sử dụng List :: Pairwise, vì nó ẩn những gì đang xảy ra theo cách mà 'map {" nhận được $ _ = Các phím $ h {$ _} "}% h' hiển thị hoàn toàn rõ ràng. Điều đó nói rằng, tôi thấy mình xây dựng danh sách các cặp * đặt hàng thường đủ, theo đó tôi có nghĩa là các danh sách thứ tự của các cặp đặt hàng. – tchrist

3

$ perl -d/dev/null

DB<2> %p = (a=>'b', c=> 'd');             
    DB<5> p Dumper \%p                
$VAR1 = { 
      'c' => 'd', 
      'a' => 'b' 
     }; 

Để ví dụ ngược lại chìa khóa và giá trị:

DB<6> %q = map { ($p{$_}, $_) } keys %p          
    DB<7> p Dumper \%q                
$VAR1 = { 
      'b' => 'a', 
      'd' => 'c' 
     }; 
+0

Như đã thấy trong câu hỏi và các câu trả lời khác, tôi biết rằng tôi có thể lặp qua các phím. Tôi đang tìm xem có giải pháp nào khác không. (Và nó là List :: Pairwise.) – Tim

0

tôi thêm này vì tôi không được phép để thêm ý kiến ​​để @eugene giải pháp. tôi thích nó, nhưng nó đã không làm việc cho tôi (thêm một print $i trong map để thấy rằng giá trị trở nên NaN) nó làm việc như thế này:

my $i = 0; 
%hash = map { ($i=($i^1)+0) ? new_key($_) : new_val($_) } %hash; 
Các vấn đề liên quan