所以,让我说我有以下例子:
struct Client {
email: String,
phone: String,
details: String
}
fn main() {
let mut clients: Vec<Client> = Vec::new();
clients.push(Client {
email: "john@gmail.com".to_string(),
phone: "0123456789".to_string(),
details: "custom details".to_string(),
});
clients.push(Client {
email: "john@gmail.com".to_string(),
phone: "0123456789".to_string(),
details: "other details".to_string(),
});
clients.push(Client {
email: "james@gmail.com".to_string(),
phone: "9876543210".to_string(),
details: "test".to_string(),
});
}
通过检查email
中的phone
和Client
来计算此向量中的部分重复项的最佳(Rust惯用)方法是什么?例如 - 在上面的示例中,将找到一个副本。
答案 0 :(得分:4)
一种选择是为每个客户创建一个HashSet
(email, phone)
。由于HashSet
仅保留唯一元素,因此我们可以获得重复元素的数量,其中集合中clients
的元素数量不同:
use std::collections::HashMap;
struct Client {
email: String,
phone: String,
details: String,
}
fn main() {
let mut clients: Vec<Client> = Vec::new();
clients.push(Client {
email: "john@gmail.com".to_string(),
phone: "0123456789".to_string(),
details: "custom details".to_string(),
});
clients.push(Client {
email: "john@gmail.com".to_string(),
phone: "0123456789".to_string(),
details: "other details".to_string(),
});
clients.push(Client {
email: "james@gmail.com".to_string(),
phone: "9876543210".to_string(),
details: "test".to_string(),
});
// use as_str to get a `&str` from a String to avoid copying the string
let uniques: HashMap<_, _> = clients.iter()
.map(|c| (c.email.as_str(), c.phone.as_str()))
.collect();
let num_dups = clients.len() - uniques.len();
assert_eq!(1, num_dups);
}
答案 1 :(得分:1)
您经常想知道哪些是重复项。在这种情况下,可以使用the HashSet
solution的直接扩展名:
// logger.lib : logger.c
static int s_log_level; // only visible to logger.c
void set_log_level(int log_level) { s_log_level = log_level; }
void log(const char* mesg) { /*...*/ }
注意在use std::collections::HashMap;
struct Client {
email: String,
phone: String,
details: String,
}
impl Client {
fn key<'a>(&'a self) -> (&'a str, &'a str) {
(&self.email, &self.phone)
}
}
fn main() {
let clients = vec![Client {
email: "john@gmail.com".to_string(),
phone: "0123456789".to_string(),
details: "custom details".to_string(),
},
Client {
email: "john@gmail.com".to_string(),
phone: "0123456789".to_string(),
details: "other details".to_string(),
},
Client {
email: "james@gmail.com".to_string(),
phone: "9876543210".to_string(),
details: "test".to_string(),
}];
let mut keyed = HashMap::new();
for c in &clients {
keyed.entry(c.key()).or_insert(vec![]).push(c)
}
for (k, v) in &keyed {
if v.len() > 1 {
println!("Key {:?} has {} duplicates!", k, v.len());
}
}
}
上使用方法将键控逻辑保持在一个位置,使用Client
来减少所需的显式可变性的数量,并且不需要指定类型可以推断出vec![]
。