【问题标题】:Consume and replace elements in a vector with 1 or more elements使用 1 个或多个元素使用和替换向量中的元素
【发布时间】:2021-01-22 10:02:48
【问题描述】:

我正在尝试找出一种有效的 Rust 方式来使用向量的元素并将它们替换为一个或多个(相同类型的)元素,就像在非编译示例中一样:

fn main() {
    let mut myvec = vec![0, 1];
    println!("{:?}", myvec);
    
    for val in myvec.drain(..) {
        myvec.push(val+2);
        myvec.push(val+4);
    }
    println!("{:?}", myvec);
}

但是,我什至不确定 Rust 是否会允许这样做,因为每个操作都需要一个可变引用(即我们需要 2 个可变引用),但 Rust 只能允许一个。有没有办法做我想做的事,还是我只需要有 2 个独立的向量:

let mut myvec = vec![0, 1];
let mut newvec = Vec::new();
println!("{:?}", myvec);
    
for val in myvec.drain(..) {
    newvec.push(val+2);
    newvec.push(val+4);
}
println!("{:?}", newvec);

哪个输出:

[0, 1]
[2, 4, 3, 5]

附言。我知道splice method 可以实现我所需要的,但我还需要在 for 循环内有一个可变引用。

【问题讨论】:

  • 鉴于您正在使 vec 更大,它可能需要重新分配,并且可能创建一个新的 Vec 不会更糟,性能方面
  • 是的,我认为没有任何简单的方法可以执行“就地平面图”。您总是可以从一端 remove() 条目并将它们添加到另一端,但是 vec 然后需要移动所有不会很快的项目(那时 vecdeque 会更有效)。实际上,您在这里会遇到同样的问题:第一个项目将替换正在耗尽的项目,但第二个项目将不得不“碰撞”向量中剩余的所有项目。

标签: rust


【解决方案1】:

由于您要更改Vec 的大小,因此很可能无论如何都需要重新分配。此外,您不能在迭代 Vec 时对其进行变异(正是因为变异它可能会导致它重新分配)。收集到新的Vec不会有太大不同:

myvec = myvec
    .drain(..)
    .flat_map(|val| iter::once(val + 2).chain(iter::once(val + 4)))
    .collect();

链式迭代器可能不是最佳的。 In nightly Rust,你可以这样做:

#![feature(array_value_iter)]

use std::array;

myvec = myvec
    .drain(..)
    .flat_map(|val| array::IntoIter::new([val + 2, val + 4]))
    .collect();

应该更有效。

【讨论】:

    【解决方案2】:

    您可以直接在内存中交换相同类型的元素:

    use core::mem::swap;
    
    fn main() {
        let mut myvec = vec![0, 1];
        let mut result = Vec::new();
        println!("{:?}", myvec);
    
        for i in (0..myvec.len()).step_by(2) {
            let mut x = myvec[i] + 2;
            swap(&mut myvec[i], &mut x);
            result.push(x);
    
            if i + 1 < myvec.len() {
                let mut y = myvec[i + 1] + 4;
                swap(&mut myvec[i + 1], &mut y);
                result.push(y);
            }
        }
    
        println!("{:?} {:?}", myvec, result);
    }
    

    发布后,我意识到您需要用多个元素替换一个元素,而这段代码不会这样做。不过,我会保留它以防万一。

    【讨论】:

      猜你喜欢
      • 2018-07-23
      • 2021-12-10
      • 2015-11-09
      • 2017-07-05
      • 2019-03-30
      • 2018-11-30
      • 2016-08-16
      • 1970-01-01
      • 2021-09-29
      相关资源
      最近更新 更多