有效地改变一个向量,同时迭代同一个向量 [英] Efficiently mutate a vector while also iterating over the same vector

查看:58
本文介绍了有效地改变一个向量,同时迭代同一个向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个结构向量,我将向量中的每个元素与每个其他元素进行比较,并在某些情况下改变当前元素.

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 is that you can't have both a mutable and immutable borrow happening at the same time, but I'm not sure how to reframe my problem to get around this without cloning either the current element or the entire vector, which seems like a waste since I'm only ever mutating the current element, and it doesn't need to be compared to itself (I skip that case).

我确信在 Rust 中有一种惯用的方法可以做到这一点.

I'm sure there's an idiomatic way to do this in Rust.

struct MyStruct {
    a: i32,
}

fn main() {
    let mut v = vec![MyStruct { a: 1 }, MyStruct { a: 2 }, MyStruct { a: 3 }];

    for elem in v.iter_mut() {
        for other_elem in v.iter() {
            if other_elem.a > elem.a {
                elem.a += 1;
            }
        }
    }
}

推荐答案

最简单的方法是使用索引,不涉及任何长期借用:

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;
        }
    }
}

如果你真的,真的想要使用迭代器,你可以通过将 Vec 分成不相交的切片来实现:

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);
    }
}

这篇关于有效地改变一个向量,同时迭代同一个向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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