将向量中的每个元素与下一个元素进行比较 [英] Comparing every element in a vector with the next one

查看:35
本文介绍了将向量中的每个元素与下一个元素进行比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将向量的每个元素与下一个元素进行比较.我找到了以下解决方案,但它不是那么可读.

I want to compare every element of a vector with the next one. I found the following solution but it is not so readable.

struct Obj {
    i: u32,
}

impl Obj {
    fn is_valid_next(&self, next: &Obj) -> bool {
        self.i + 1 == next.i
    }
}

fn main() {
    let data: Vec<Obj> = vec![Obj { i: 0 }, Obj { i: 2 }, Obj { i: 2 }];
    let mut previous: Option<Obj> = None;
    let mut is_valid = true;
    for current in data.into_iter() {
        match previous {
            Some(p) => {
                is_valid = p.is_valid_next(&current);
                if !is_valid {
                    break;
                }
            }
            None => {}
        }
        previous = Some(current);
    }
    println!("is valid {}", is_valid);
}

推荐答案

这可以通过多种方式完成.

This can be done in several ways.

slice::windows:

在所有长度大小的连续窗口上返回迭代器.

Returns an iterator over all contiguous windows of length size.

在这种情况下,窗口大小将为 2,因此 windows 将返回一个迭代器,该迭代器将屏蔽 2 个元素,并在每次迭代时向右移动.

In this case, the window size will be 2 so windows will return an iterator which will mask 2 elements and it will move to the right on every iteration.

initial position : [|0, 5|, 10, 40, 30] // &[0, 5]
next position    : [0, |5, 10|, 40, 30] // &[5, 10]

这是您的问题的应用解决方案:

Here is an applied solution to your problem:

fn main() {
    let data: Vec<Obj> = vec![Obj { i: 0 }, Obj { i: 1 }, Obj { i: 2 }, Obj { i: 3 }];

    let is_valid = data.windows(2).all(|w| w[0].is_valid_next(&w[1]));

    println!("Is consecutive -> {:?}", is_valid); // true
}

游乐场

请注意,切片的直接索引访问可能会导致 panic,但由于从 Windows 迭代器生成的切片将与 的参数大小相同>windows,只要索引小于窗口大小就可以直接通过索引访问元素.

Please note that direct index access of a slice might cause a panic, but since the produced slice from Windows iterator will be the same size as the argument to windows, it will be fine to access elements directly by index as long as the index is less than the window size.

您可以使用两个具有相同 Vecstd::iter::Zip 的不同迭代器来比较当前元素和下一个元素.

You can compare the current element with the next one by using two different iterators of same Vec with std::iter::Zip.

来自第一个迭代器 (data.iter()) 的迭代器元素将代表当前元素.来自第二个迭代器 (data.iter().skip(1)) 的元素将代表下一个元素.

The iterator elements from the first iterator (data.iter()) will represent the current element. Elements from the second iterator (data.iter().skip(1)) will represent the next element.

这是实现:

fn main() {
    let data: Vec<Obj> = vec![Obj { i: 0 }, Obj { i: 1 }, Obj { i: 2 }];

    let is_valid = data
        .iter()
        .zip(data.iter().skip(1))
        .all(|(current, next)| current.is_valid_next(next));

    println!("Is consecutive -> {:?}", is_valid); // true
}

游乐场

如果您确定您的 Vec 不为空,您可以使用切片来创建迭代器:&data[1..] 而不是 data.iter().skip(1) (示例).如果您有一个空的 Vec,这将导致恐慌.

If you are sure your Vec is not empty, you can use slices to create the iterators: &data[1..] instead of data.iter().skip(1) (sample). This will panic if you have an empty Vec.

这篇关于将向量中的每个元素与下一个元素进行比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆