Comparing every element in a vector with the next one

后端 未结 1 1922
野趣味
野趣味 2020-12-20 02:39

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         


        
相关标签:
1条回答
  • 2020-12-20 03:02

    This can be done in several ways.

    Using slice::windows

    slice::windows:

    Returns an iterator over all contiguous windows of length size.

    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
    }
    

    Playground

    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.

    Using Iterator::zip

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

    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.

    Here is the implementation:

    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
    }
    

    Playground

    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.

    0 讨论(0)
提交回复
热议问题