根据索引在循环中删除向量的元素
Remove elements of vector in a loop based on index
假设我有一个向量,值是从 1 到 10。我希望如果你发现 5 和 5 彼此相邻,将它们连同下一个元素一起删除。
输入
[1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10]
预期输出
[1, 2, 3, 4]
这是我的尝试。我正在寻找要删除的索引,但借用规则让我卡住了。
let mut element = vec![1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10];
for (index, val) in element.iter().enumerate() {
if *val == 5 {
if let Some(next_val) = element.get(index + 1) {
if *next_val == 5 {
//element.drain(index..);
}
}
}
}
Rust 让您免于迭代器失效(其他语言中常见的错误来源)。当您尝试在并发迭代数据结构的同时修改数据结构时,通常会发生这种错误。调用 element.drain(index..)
后,您无法移动到(现已删除的)下一个元素。所以你需要在那个点之后添加一个break
以避免内存不安全。
在这种情况下,只需添加 break;
就足以使代码通过编译。但是,要获得更简洁的线性解决方案,请充分利用标准库提供的迭代器和方法:
if let Some(index) = element.windows(2).position(|pair| pair[0] == pair[1]) {
element.truncate(index);
}
切片上的 windows(2)
给出长度为 2 的子切片上的迭代器,并且 position
调用 returns 该迭代器的第一个元素的索引,其中的两个元素切片是相等的。 (如果不存在这样的对,position
returns None
。)
我发现 position
闭包随着(当前不稳定的)array_windows
特征变得更加明显:
if let Some(index) = element.array_windows().position(|[x, y]| x == y) {
element.truncate(index);
}
相关
你不能做你想做的事,因为你想在迭代向量时从向量中删除一些元素。这是一个很大的错误。请注意,从 vector 中删除任何元素都会使迭代器无效,因此您将访问意想不到的位置,因此 rust 不允许 UB
s
你可以使用类似下面的东西
let mut elements = vec![1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10];
let mut first_repeated_five_index_op = None;
for index in 0..elements.len()-1{
if elements[index] == 5 && elements[index + 1] == 5{
first_repeated_five_index_op = Some(index);
break;
}
}
if let Some(first_repeated_five_index) = first_repeated_five_index_op{
elements.truncate(first_repeated_five_index);
}
println!("{:?}", elements);
看到一个Demo
假设我有一个向量,值是从 1 到 10。我希望如果你发现 5 和 5 彼此相邻,将它们连同下一个元素一起删除。
输入
[1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10]
预期输出
[1, 2, 3, 4]
这是我的尝试。我正在寻找要删除的索引,但借用规则让我卡住了。
let mut element = vec![1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10];
for (index, val) in element.iter().enumerate() {
if *val == 5 {
if let Some(next_val) = element.get(index + 1) {
if *next_val == 5 {
//element.drain(index..);
}
}
}
}
Rust 让您免于迭代器失效(其他语言中常见的错误来源)。当您尝试在并发迭代数据结构的同时修改数据结构时,通常会发生这种错误。调用 element.drain(index..)
后,您无法移动到(现已删除的)下一个元素。所以你需要在那个点之后添加一个break
以避免内存不安全。
在这种情况下,只需添加 break;
就足以使代码通过编译。但是,要获得更简洁的线性解决方案,请充分利用标准库提供的迭代器和方法:
if let Some(index) = element.windows(2).position(|pair| pair[0] == pair[1]) {
element.truncate(index);
}
切片上的 windows(2)
给出长度为 2 的子切片上的迭代器,并且 position
调用 returns 该迭代器的第一个元素的索引,其中的两个元素切片是相等的。 (如果不存在这样的对,position
returns None
。)
我发现 position
闭包随着(当前不稳定的)array_windows
特征变得更加明显:
if let Some(index) = element.array_windows().position(|[x, y]| x == y) {
element.truncate(index);
}
相关
你不能做你想做的事,因为你想在迭代向量时从向量中删除一些元素。这是一个很大的错误。请注意,从 vector 中删除任何元素都会使迭代器无效,因此您将访问意想不到的位置,因此 rust 不允许 UB
s
你可以使用类似下面的东西
let mut elements = vec![1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10];
let mut first_repeated_five_index_op = None;
for index in 0..elements.len()-1{
if elements[index] == 5 && elements[index + 1] == 5{
first_repeated_five_index_op = Some(index);
break;
}
}
if let Some(first_repeated_five_index) = first_repeated_five_index_op{
elements.truncate(first_repeated_five_index);
}
println!("{:?}", elements);
看到一个Demo