2016-01-01 26 views
11

Tôi muốn sắp xếp dữ liệu HashMap theo giá trị trong Rust (ví dụ: khi tính tần suất ký tự trong một chuỗi).Sắp xếp dữ liệu HashMap theo giá trị

Các Python tương đương với những gì tôi đang cố gắng làm là:

count = {} 
for c in text: 
    count[c] = count.get('c', 0) + 1 

sorted_data = sorted(count.items(), key=lambda item: -item[1]) 

print('Most frequent character in text:', sorted_data[0][0]) 

đang Rust tương ứng của tôi trông như thế này:

// Count the frequency of each letter 
let mut count: HashMap<char, u32> = HashMap::new(); 
for c in text.to_lowercase().chars() { 
    *count.entry(c).or_insert(0) += 1; 
} 

// Get a sorted (by field 0 ("count") in reversed order) list of the 
// most frequently used characters: 
let mut count_vec: Vec<(&char, &u32)> = count.iter().collect(); 
count_vec.sort_by(|a, b| b.1.cmp(a.1)); 

println!("Most frequent character in text: {}", count_vec[0].0); 

là Rust thành ngữ này? Tôi có thể xây dựng count_vec theo cách sao cho nó sẽ tiêu thụ dữ liệu HashMaps và sở hữu nó (ví dụ: sử dụng map())? Điều này có phải là idomatic hơn?

Trả lời

6

Thành ngữ này có phải là Rust không?

Không có gì đặc biệt unidiomatic, trừ thể cho không cần thiết đầy đủ loại hạn chế về count_vec; bạn chỉ có thể sử dụng

let mut count_vec: Vec<_> = count.iter().collect(); 

Không khó trong ngữ cảnh để tìm ra loại đầy đủ của count_vec. Bạn có thể cũng bỏ ràng buộc loại cho counthoàn toàn, nhưng sau đó bạn phải chơi shenanigans với các chữ số nguyên của bạn để có loại giá trị đúng được phỏng đoán. Đó là để nói, một chú thích rõ ràng là eminently hợp lý trong trường hợp này.

Các khác thay đổi ranh giới bạn có thể làm nếu bạn cảm thấy như nó sẽ được sử dụng cho việc đóng cửa |a, b| a.1.cmp(b.1).reverse() loại. Phương thức Ordering::reverse chỉ đảo ngược kết quả sao cho nhỏ hơn trở thành lớn hơn và ngược lại. Điều này làm cho nó rõ ràng hơn một chút rằng bạn có nghĩa là những gì bạn đã viết, như trái ngược với vô tình transposing hai chữ cái.

Tôi có thể tạo count_vec theo cách sao cho nó sẽ tiêu thụ dữ liệu HashMaps và sở hữu dữ liệu đó không?

Không có cách nào có ý nghĩa. Chỉ vì HashMap đang sử dụng bộ nhớ không có nghĩa là bộ nhớ tương thích với Vec. Bạn có thể sử dụng count.into_iter() để tiêu thụ các HashMap và di chuyển các phần tử (trái ngược với lặp qua con trỏ), nhưng vì cả hai charu32 đều có thể sao chép được, điều này thực sự không giúp bạn gì cả.

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