2016-01-01 45 views
11

HashMapデータをRustの値でソートしたい(文字列の文字頻度を数える場合など)。私は何をしようとしているの値でHashMapデータをソート

ザ・Pythonの同等は次のとおりです。

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]) 

マイ対応錆コードは次のようになります。

// 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); 

は、この慣用的な錆ですか? count_vecを、HashMapsデータを消費して所有するように構築することはできますか(たとえば、map()を使用)。これはより愚かではないか?

答えて

6

この慣用的な錆ですか?

何がおそらくcount_vec上の不要な完全な型の制約のため除いて、特にunidiomaticありません。あなたはそれがcount_vecの完全な種類が何であるかを動作するように文脈から難しいことではありません

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

を使用することができます。 count完全にの型制約を省略することもできますが、正しい値型を推論するには、整数リテラルで偽名を使用する必要があります。つまり、明示的なアノテーションはこの場合非常に合理的です。

あなたはそれソート閉鎖のため|a, b| a.1.cmp(b.1).reverse()を用いることであろうように感じる場合は、を作ることができる境界線の変更。 Ordering::reverseメソッドは結果を逆転して、より小さいがより大きい、またはその逆になるようにします。これにより、誤って2つの文字を転置するのではなく、あなたが書いたものがの意味はであることが少し明らかになります。

count_vecをHashMapsデータを消費して所有するように構築できますか?

意味がありません。 HashMapがメモリを使用しているからといって、メモリが何らかの形でVecと互換性があるとは限りません。 count.into_iter()からまではHashMapを使用し、要素を(ポインタを反復するのではなく)移動することができますが、charu32の両方が簡単にコピーできるので、実際には何も得られません。