Rust 从通过迭代找到的BTreeMap或BTreeSet中删除项
我想从Rust 从通过迭代找到的BTreeMap或BTreeSet中删除项,rust,Rust,我想从BTreeMap中删除通过迭代找到的项目 由于迭代时无法删除项,因此我将要删除的项放入一个向量中。主要问题是不可能使用参考向量,而只能使用值向量。然后必须克隆必须删除其条目的所有键(假设该键实现了克隆特征) 例如,此简短示例不编译: use std::collections::BTreeMap; pub fn clean() { let mut map = BTreeMap::<String, i32>::new(); let mut to_delete =
BTreeMap
中删除通过迭代找到的项目
由于迭代时无法删除项,因此我将要删除的项放入一个向量中。主要问题是不可能使用参考向量,而只能使用值向量。然后必须克隆必须删除其条目的所有键(假设该键实现了克隆
特征)
例如,此简短示例不编译:
use std::collections::BTreeMap;
pub fn clean() {
let mut map = BTreeMap::<String, i32>::new();
let mut to_delete = Vec::new();
{
for (k, v) in map.iter() {
if *v > 10 {
to_delete.push(k);
}
}
}
for k in to_delete.drain(..) {
map.remove(k);
}
}
fn main() {}
将更改为_delete.push(k)
并将更改为_delete.push(k.clone())
可以正确编译此代码段,但如果必须克隆每个要删除的键,则成本相当高
有更好的解决方案吗?TL;医生:你不能
就编译器而言,的实现可能会做到这一点:
pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
// actual deleting code, which destroys the value in the set
// now what `value` pointed to is gone and `value` points to invalid memory
// And now we access that memory, causing undefined behavior
key.borrow();
}
另见:
BTreeMap
能够获得类似于fn drain(&mut self,Range)
的方法。“相关的是,但也要检查一下,”@Shepmaster——当然,这里的问题是它不是范围,而是范围Range@Jsor啊,我错过了。我觉得这不太可能,所以这确实是一个棘手的问题!这里需要的是一个版本的drain
使用谓词,这确实是一个值得添加的内容。这是一个有趣的想法。请注意,根据映射的大小和要删除的元素的数量,这在性能方面不是一个明显的增益。
use std::collections::BTreeMap;
pub fn main() {
let mut map = BTreeMap::new();
map.insert("thief", 5);
map.insert("troll", 52);
map.insert("gnome", 7);
let map: BTreeMap<_, _> =
map.into_iter()
.filter(|&(_, v)| v <= 10)
.collect();
println!("{:?}", map); // troll is gone
}
use std::collections::BTreeMap;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Monster(String);
use std::borrow::Borrow;
impl Borrow<str> for Monster {
fn borrow(&self) -> &str { &self.0 }
}
pub fn main() {
let mut map = BTreeMap::new();
map.insert(Monster("thief".into()), 5);
map.insert(Monster("troll".into()), 52);
map.insert(Monster("gnome".into()), 7);
map.remove("troll");
println!("{:?}", map); // troll is gone
}