如何在Rust中短路检查向量所有元素是否处于指定区间
如何在Rust中短路检查向量所有元素是否处于指定区间
嗨,这个问题问得太实在了!你当前的写法确实有点“绕远路”——先遍历所有元素生成布尔值列表,再把列表存进内存,最后还要再遍历一次找不符合的项,整整三次遍历不说,还额外占了内存,完全可以换成更高效的短路实现。
其实Rust的迭代器早就给我们准备了完美的工具:all 方法!这个方法就是专门用来做短路式全量检查的——它会逐个过元素,只要碰到第一个不满足条件的元素,立刻就停手返回false;只有等所有元素都通过检查,才会返回true,完全符合你想要的短路效果。
用all重写你的逻辑超简单,两种写法任你选:
第一种用直接的比较运算符,直观又易懂:
let all_in_range = x_coordinates.iter().all(|&x| x_min <= x && x <= x_max);
第二种沿用你原来的区间思路,代码更简洁:
let all_in_range = x_coordinates.iter().all(|x| (x_min..=x_max).contains(x));
这里要提一句,因为iter()返回的是元素的引用(&i16),而RangeInclusive<i16>的contains方法天生支持接收&i16参数,所以不用额外解引用,直接传x就行。
给你整个完整的小例子感受下:
fn main() { let x_min: i16 = 3; let x_max: i16 = 12; let good_coords = vec![4, 7, 9, 11]; let bad_coords = vec![4, 15, 9, 11]; // 检查合规向量 println!("合规向量所有元素都在区间里吗?{}", good_coords.iter().all(|x| (x_min..=x_max).contains(x))); // 输出true // 检查不合规向量——碰到15就立刻停止遍历,直接返回false println!("不合规向量所有元素都在区间里吗?{}", bad_coords.iter().all(|x| (x_min..=x_max).contains(x))); // 输出false }
对比你之前的写法,这个实现只需要一次遍历,中途还能提前终止,既省内存又跑得快,完美解决你的问题。
要是以后你想反过来检查“有没有元素不在区间里”,可以用any方法,它也是短路的——找到第一个不符合的元素就直接返回true:
let has_outlier = x_coordinates.iter().any(|x| !(x_min..=x_max).contains(x));
内容来源于stack exchange




