[英]How to reverse map of objects to vector of tuples by using an iterator?
使用迭代器將HashMap<String, String>
轉換為Vec<(String, Vec<String>)>
的最簡單方法是什么? 我想反轉地圖。
我試圖使用iter()
方法,但不知道如何在以下情況下執行正確的map
閉合實現以收集值:
fn get_aliases(&self) -> Vec<(String, Vec<String>)> {
let mut aliases: HashMap<String, String> = HashMap::new();
aliases.insert("a".to_owned(), "test".to_owned());
aliases.insert("b".to_owned(), "test".to_owned());
aliases.insert("c".to_owned(), "test2".to_owned());
aliases.iter().map(|(ref a, ref c)| {
// what to do here?
}).collect()
// the expected return value is:
// [("test", ["a", "b"]), ("test2", ["c"])]
}
此函數將返回一個向量,該向量說明哪些String
鍵屬於某個對象。
我可以用for
和find
編寫很多代碼,但是在我看來這效率較低,我認為有一種方法可以僅使用迭代器來實現。
我可以用
for
和find
編寫很多代碼,但是在我看來這效率較低,我認為有一種方法可以僅使用迭代器來實現。
我不會調用很多代碼,並且請記住for
循環在迭代器上運行 。 我還沒有進行任何基准測試,但是這要簡單得多,並且我希望它會表現得更好:
use std::collections::HashMap;
fn get_aliases(aliases: HashMap<String, String>) -> Vec<(String, Vec<String>)> {
let mut x = HashMap::new();
for (k, v) in aliases {
x.entry(v).or_insert_with(Vec::new).push(k)
}
x.into_iter().collect()
}
fn main() {
let mut aliases = HashMap::new();
aliases.insert("a".to_owned(), "test".to_owned());
aliases.insert("b".to_owned(), "test".to_owned());
aliases.insert("c".to_owned(), "test2".to_owned());
println!("{:?}", get_aliases(aliases));
}
它並不瑣碎,當然不像其他一些提供必要功能的流庫那樣瑣碎。
您可以使用itertools板條箱的group_by
按某個鍵對元素進行分組。 但是,它僅對相鄰元素進行分組,因此您必須先對其進行排序。 這是我的結果:
impl A {
pub fn get_aliases(&self) -> Vec<(String, Vec<String>)> {
// Get a Vec of string references for sorting. Reverse element
// order for clarity.
let mut v = self.aliases.iter()
.map(|(a, c)| (&c[..], &a[..])).collect::<Vec<_>>();
v.sort_by_key(|t| t.0); // Make identical keys adjacent.
let g = v.into_iter().group_by(|t| t.0); // Create grouping.
g.into_iter()
.map(|(key, group)| // key is the str with the key
// group is a subiterator that just visits
// elements with that key, Item=&(&str,&str)
(key.to_string(), // result is a tuple of the key as String
group.map(|t| t.1.to_string()).collect())
// and the subiterator turned into a Vec<String>
)
.collect() // finally, turn Iterator<Item=(String, Vec<String>) into Vec
}
}
回到最初的問題,如果Object
是,則還有一個問題,即Arc<Object>
僅是PartialEq
( group_by
所需)。 與Ord
相同(需要sort_by_key
)。 如果無法通過這種方式比較Object
類型,並且要使用指針標識,則中間向量將需要在Arc
周圍存儲一些使用指針值進行比較的新型包裝器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.