在可变Vec中弹出最后N个元素的惯用方法是什么?

时间:2015-03-09 21:50:41

标签: rust

我正在向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 link

3 个答案:

答案 0 :(得分:8)

我建议使用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![]轻松构建数字向量
  • 一次打印出整个矢量

通常当你&#34; pop&#34;什么,你想拥有这些价值观。如果您想要另一个向量中的值,可以使用Vec::split_off

let tail = nums.split_off(final_length);

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

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

答案 1 :(得分:3)

另一种方法是使用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);
    }
}

排水方法接受RangeArgument形式的<start-inclusive>..<end-exclusive>。默认为向量的开始/结束,可以省略start和end。所以上面,我们真的只是说从new_len开始并且直到最后。

答案 2 :(得分: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)
    }
}