如何以惯用方式弹出可变向量中的最后N个元素?

24

我正在向RosettaCode贡献Rust代码,旨在学习Rust并同时为Rust社区做出贡献。如何以最佳惯用方式从可变的Vec中弹出最后的n个元素?

以下是我大致编写的代码,但我希望看看是否有更好的方法:

fn main() {
    let mut nums: Vec<u32> = Vec::new();
    nums.push(1);
    nums.push(2);
    nums.push(3);
    nums.push(4);
    nums.push(5);

    let n = 2;
    for _ in 0..n {
        nums.pop();
    }

    for e in nums {
        println!("{}", e)
    }
}

(Playground 链接)

3个回答

31

我建议使用Vec :: truncate

fn main() {
    let mut nums = vec![1, 2, 3, 4, 5];

    let n = 2;
    let final_length = nums.len().saturating_sub(n);
    nums.truncate(final_length);

    println!("{:?}", nums);
}

此外,我:

  • 使用saturating_sub来处理向量中没有N个元素的情况。
  • 使用vec![]轻松构建数字向量。
  • 一次性打印整个向量。

通常,当你“弹出”某些东西时,你希望保留这些值。如果你想将这些值存入另一个向量中,可以使用Vec::split_off

let tail = nums.split_off(final_length);

如果你想要访问元素,但又不想创建一个全新的向量,可以使用Vec::drain方法:

for i in nums.drain(final_length..) {
    println!("{}", i)
}

7

另一种方法是使用Vec::drain。这将提供一个迭代器,因此您可以实际使用被移除的元素。

fn main() {
    let mut nums: Vec<u32> = Vec::new();
    nums.push(1);
    nums.push(2);
    nums.push(3);
    nums.push(4);
    nums.push(5);

    let n = 2;
    let new_len = nums.len() - n;

    for removed_element in nums.drain(new_len..) {
        println!("removed: {}", removed_element);
    }

    for retained_element in nums {
        println!("retained: {}", retained_element);
    }
}

drain 方法接受一个形如 <start-inclusive>..<end-exclusive>RangeArgument。起始位置和结束位置都可以省略,以默认为向量的开头/结尾。因此,上面的代码实际上是从 new_len 开始并耗尽到末尾。

那么如何从切片中删除一些元素? - chenzhongpu
@chenzhongpu slice_variable = &slice_variable[..new_len];@陈中普 slice_variable = &slice_variable[..new_len]; - Chai T. Rex

2
您可以查看标准库中的Vec::truncate函数,它可以帮助您完成此操作。
playground
fn main() {
    let mut nums: Vec<u32> = Vec::new();
    nums.push(1);
    nums.push(2);
    nums.push(3);
    nums.push(4);
    nums.push(5);

    let n = 2;
    let new_len = nums.len() - n;
    nums.truncate(new_len);

    for e in nums {
        println!("{}", e)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接