2010-08-27 37 views
6

Tôi có một băm băm, như vậy:Làm cách nào để ánh xạ (và sắp xếp) các giá trị từ băm băm?

 
%hash = (a => { b => 1, c =>2, d => 3}, 
      a1 => { b => 11, c =>12, d => 13}, 
      a2 => { b => 21, c =>22, d => 23}) 

tôi muốn trích xuất các yếu tố "b" và đặt nó vào một mảng. Ngay bây giờ, tôi đang lặp qua băm để làm điều này, nhưng tôi nghĩ rằng tôi có thể cải thiện hiệu quả một chút bằng cách sử dụng bản đồ để thay thế. Tôi khá chắc chắn rằng nếu điều này là một mảng băm, tôi muốn sử dụng một cái gì đó như thế này:

 
@hasharray = ({ b => 1, c =>2, d => 3}, 
       { b => 11, c =>12, d => 13}, 
       { b => 21, c =>22, d => 23}) 
@array = map { ($_->{b} => $_) } @hasharray 

Hãy tha thứ cho tôi nếu tôi sai, tôi vẫn đang học cách đồ hoạt động. Nhưng những gì tôi muốn biết là làm thế nào tôi sẽ đi về lập bản đồ băm của băm? Điều này thậm chí có thể sử dụng bản đồ? Tôi chưa tìm thấy bất kỳ ví dụ nào về việc này.

Thậm chí tốt hơn, bước tiếp theo trong mã này là sắp xếp mảng sau khi được điền. Tôi khá chắc chắn điều này là có thể, nhưng tôi không đủ thông minh về việc sử dụng bản đồ để tìm ra chính bản thân mình. Làm thế nào tôi sẽ đi về việc này tất cả trong một shot?

Cảm ơn. Seth

Trả lời

11

chiết xuất này và sắp xếp tất cả "b" s:

my @array = sort { $a <=> $b } map $_->{b}, values %hash; 
+0

Điều đó làm việc tuyệt vời, chính xác những gì tôi đang tìm kiếm. Tôi đã thay thế 26 dòng mã bằng mã này và cải thiện hiệu năng của hàm đó từ khoảng O (n) thành O (1). Cảm ơn! – sgsax

+1

Vâng, nó vẫn phải lặp qua các giá trị của băm và sắp xếp chúng, vì vậy nó không thực sự là O (1). – Corey

1

Hãy giải pháp thứ hai của bạn, và thay thế values %hash cho @hasharray:

@array = map { ($_->{b} => $_) } values %hash; 

(. Và đừng quên ; chấm dứt tuyên bố)

3

Điều này điền @array với danh sách sắp xếp tham chiếu mảng, mỗi chứa giá trị b và hashref của nó.

my @array = sort {$$a[0] <=> $$b[0]} 
      map { [$$_{b} => $_] } 
      values %hash; 

my @sorted_hashes = map {$$_[1]} @array; 
+1

'$ a -> [0]' dễ đọc hơn '$$ a [0]'; tương tự '$ _-> {b}' thay vì '$$ _ {b}'. –

+0

Tốt hơn nên sử dụng toán tử '<=>' thay vì 'cmp' khi sắp xếp các số. –

+0

@eugene => điểm tốt, sửa chữa. @Philip => Tôi thích sigils tăng gấp đôi vì hai lý do. Đầu tiên, nó giữ với các hình thức dereferencing khác như '@ $ a [1, 2]'. Thứ hai, toán tử '->' được sử dụng cho các cuộc gọi phương thức, vì vậy tôi chỉ thích sử dụng nó trong các tình huống mà mã được gọi. –

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