Efficiently mutate a vector while also iterating over the same vector

后端 未结 2 1143
北海茫月
北海茫月 2020-11-27 08:13

I have a vector of structs, and I\'m comparing every element in the vector against every other element, and in certain cases mutating the current element.

My issue

相关标签:
2条回答
  • 2020-11-27 08:52

    The simplest way is to just use indices, which don't involve any long-lived borrows:

    for i in 0..v.len() {
        for j in 0..v.len() {
            if i == j { continue; }
            if v[j].a > v[i].a {
                v[i].a += 1;
            }
        }
    }
    

    If you really, really want to use iterators, you can do it by dividing up the Vec into disjoint slices:

    fn process(elem: &mut MyStruct, other: &MyStruct) {
        if other.a > elem.a {
            elem.a += 1;
        }
    }
    
    for i in 0..v.len() {
        let (left, mid_right) = v.split_at_mut(i);
        let (mid, right) = mid_right.split_at_mut(1);
        let elem = &mut mid[0];
    
        for other in left {
            process(elem, other);
        }
        for other in right {
            process(elem, other);
        }
    }
    
    0 讨论(0)
  • 2020-11-27 09:01

    If you can modify type type of v, and the elements of v are Copy, you can wrap MyStruct in Cell.

    #[derive(Copy, Clone)] 
    struct MyStruct {
        a: i32,
    }
    
    fn main() {
        use std::cell::Cell;
        let v = vec![
            Cell::new(MyStruct { a: 1 }),
            Cell::new(MyStruct { a: 2 }),
            Cell::new(MyStruct { a: 3 }),
        ];
    
        for elem in v.iter() {
            for other_elem in v.iter() {
                let mut e = elem.get();
                if other_elem.get().a > e.a {
                    e.a += 1;
                    elem.set(e);
                }
            }
        }
    }
    

    If instead you're passed a &mut to a slice (or &mut that can be converted into a slice), use Cell::from_mut and Cell::as_slice_of_cells and use the same trick as above (assuming the elements of the slice are Copy).

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