为什么在向量上调用过滤器不会从向量中删除元素?
Why does calling filter on a vector not remove elements from the vector?
我正在编写一个小程序来寻找马拉松比赛的获胜者。
在我尝试为迟到一段时间的跑步者过滤矢量之前,一切似乎都是合乎逻辑的。向量在过滤器函数之后保持不变,如果使用 iter_mut()
它会指出类型错误。
fn main() {
let mut input_line = String::new();
std::io::stdin().read_line(&mut input_line);
let n = input_line.trim().parse::<u8>().unwrap();
let mut v = Vec::with_capacity(n as usize);
for _ in 0..n {
let mut input_line = String::new();
std::io::stdin().read_line(&mut input_line);
let separated = input_line.trim().split(":").collect::<Vec<_>>();
let hours = separated[0].parse::<u8>().unwrap();
let minutes = separated[1].parse::<u8>().unwrap();
let seconds = separated[2].parse::<u8>().unwrap();
v.push((hours, minutes, seconds));
}
//println!("{:?}", v);
filter_hours(&mut v);
filter_minutes(&mut v);
filter_seconds(&mut v);
println!("{:?}", v[0]);
println!("{:?}", v);
}
fn filter_hours(v: &mut Vec<(u8, u8, u8)>) {
let (mut minimum, _, _) = v[0];
for &i in v.iter() {
let (h, _, _) = i;
if h < minimum {
minimum = h;
}
}
v.iter().filter(|&&(h, _, _)| h == minimum);
}
fn filter_minutes(v: &mut Vec<(u8, u8, u8)>) {
let (_, mut minimum, _) = v[0];
for &i in v.iter() {
let (_, m, _) = i;
if m < minimum {
minimum = m;
}
}
v.iter().filter(|&&(_, m, _)| m == minimum);
}
fn filter_seconds(v: &mut Vec<(u8, u8, u8)>) {
let (_, _, mut minimum) = v[0];
for &i in v.iter() {
let (_, _, s) = i;
if s < minimum {
minimum = s;
}
}
v.iter().filter(|&&(_, _, s)| s == minimum);
}
请注意,filter
操作的是迭代器,而不是向量;它从迭代器而不是向量中移除元素。做你想做的一种方法是将 filter
的结果收集到一个新向量中并用它替换旧向量:v = v.iter().filter(whatever).collect();
但这将为新向量分配 space,复制将旧向量中的元素放入新向量中,然后释放旧向量。
有一个实验性的 API、drain_filter
,它允许您修改矢量并删除适当的匹配元素。但是由于它是实验性的,这个 API 暂时只能在夜间使用。
如果你想保持稳定的 Rust 并避免 collect
的开销,你将需要手动删除元素。应该这样做(取自 drain_filter
文档):
let mut i = 0;
while i != vec.len() {
if some_predicate(&mut vec[i]) {
let val = vec.remove(i);
// your code here
} else {
i += 1;
}
}
迭代器不会改变原始数据结构中的项数。相反,您想使用 retain
:
fn filter_hours(v: &mut Vec<(u8, u8, u8)>) {
let min = v.iter().map(|&(h, _, _)| h).min().unwrap();
v.retain(|&(h, _, _)| h == min);
}
我正在编写一个小程序来寻找马拉松比赛的获胜者。
在我尝试为迟到一段时间的跑步者过滤矢量之前,一切似乎都是合乎逻辑的。向量在过滤器函数之后保持不变,如果使用 iter_mut()
它会指出类型错误。
fn main() {
let mut input_line = String::new();
std::io::stdin().read_line(&mut input_line);
let n = input_line.trim().parse::<u8>().unwrap();
let mut v = Vec::with_capacity(n as usize);
for _ in 0..n {
let mut input_line = String::new();
std::io::stdin().read_line(&mut input_line);
let separated = input_line.trim().split(":").collect::<Vec<_>>();
let hours = separated[0].parse::<u8>().unwrap();
let minutes = separated[1].parse::<u8>().unwrap();
let seconds = separated[2].parse::<u8>().unwrap();
v.push((hours, minutes, seconds));
}
//println!("{:?}", v);
filter_hours(&mut v);
filter_minutes(&mut v);
filter_seconds(&mut v);
println!("{:?}", v[0]);
println!("{:?}", v);
}
fn filter_hours(v: &mut Vec<(u8, u8, u8)>) {
let (mut minimum, _, _) = v[0];
for &i in v.iter() {
let (h, _, _) = i;
if h < minimum {
minimum = h;
}
}
v.iter().filter(|&&(h, _, _)| h == minimum);
}
fn filter_minutes(v: &mut Vec<(u8, u8, u8)>) {
let (_, mut minimum, _) = v[0];
for &i in v.iter() {
let (_, m, _) = i;
if m < minimum {
minimum = m;
}
}
v.iter().filter(|&&(_, m, _)| m == minimum);
}
fn filter_seconds(v: &mut Vec<(u8, u8, u8)>) {
let (_, _, mut minimum) = v[0];
for &i in v.iter() {
let (_, _, s) = i;
if s < minimum {
minimum = s;
}
}
v.iter().filter(|&&(_, _, s)| s == minimum);
}
请注意,filter
操作的是迭代器,而不是向量;它从迭代器而不是向量中移除元素。做你想做的一种方法是将 filter
的结果收集到一个新向量中并用它替换旧向量:v = v.iter().filter(whatever).collect();
但这将为新向量分配 space,复制将旧向量中的元素放入新向量中,然后释放旧向量。
有一个实验性的 API、drain_filter
,它允许您修改矢量并删除适当的匹配元素。但是由于它是实验性的,这个 API 暂时只能在夜间使用。
如果你想保持稳定的 Rust 并避免 collect
的开销,你将需要手动删除元素。应该这样做(取自 drain_filter
文档):
let mut i = 0;
while i != vec.len() {
if some_predicate(&mut vec[i]) {
let val = vec.remove(i);
// your code here
} else {
i += 1;
}
}
迭代器不会改变原始数据结构中的项数。相反,您想使用 retain
:
fn filter_hours(v: &mut Vec<(u8, u8, u8)>) {
let min = v.iter().map(|&(h, _, _)| h).min().unwrap();
v.retain(|&(h, _, _)| h == min);
}