如何修改枚举的向量

时间:2015-10-20 17:39:37

标签: rust

我想过滤掉Option向量中的一些项目,我想在不创建新向量的情况下这样做,因为它可以通过map和{{的组合来完成1}}。我不想使用collect,因为这已被弃用。

我找到了以下解决方案:

Vec::map_in_place

(playpen)

虽然它工作正常,但每个元素都会生成2个副本,无论元素是否被修改。

是否有更惯用的解决方案还需要更少的复制?

2 个答案:

答案 0 :(得分:2)

弗拉基米尔的评论后

冒着大规模过度拟合的具体例子;以下内容也适用:

fn main() {
    let mut v = vec![Some("10".to_owned()), Some("5".to_owned()),
                     None, Some("20".to_owned())];

    for i in v.iter_mut() {
        if i.as_ref().map_or(false, |f| *f == "20") {
            i.take();
        }
    }
    println!("v = {:?}", v);
}

初步答案

也许你过分简化了你的例子,但对于给定的程序,如果只能用一个副本完成,并且只在需要更改时。主要的想法是,您首先要检查是否需要更改(即iSome("20")),然后您只需进行更改。借用借来的小舞似乎是必要的,但解决办法如下:

use std::mem;

fn main() {
    let mut v = vec![Some("10".to_owned()), Some("5".to_owned()),
                     None, Some("20".to_owned())];

    for i in v.iter_mut() {
        // Borrowchk-dance: make sure this borrow of i ends before we try to mutate
        let is_a_twenty = match i {
            &mut Some(ref f) if *f == "20" => true,
            _ => false,
        };
        // Now that we're free to borrow i mutably, go ahead and do so
        if is_a_twenty {
            mem::replace(i, None);
        }

    }
    println!("v = {:?}", v);
}

答案 1 :(得分:0)

这里有两种更直接的方法,一种使用 for 循环,一种使用迭代器:

fn g(number_strings: &mut Vec<Option<String>>, target: &str) {
    for some_string in number_strings.iter_mut() {
        if let Some(ref string) = some_string {
            if string == target {
                *some_string = None;
            }
        }
    }
}

fn h(number_strings: &mut Vec<Option<String>>, target: &str) {
    number_strings
        .iter_mut()
        .filter(|s| s.is_some() && s.as_ref().unwrap() == target)
        .for_each(|s| *s = None);
}

fn main() {
    let mut v = vec![
        Some("10".to_owned()),
        Some("5".to_owned()),
        None,
        Some("20".to_owned()),
        Some("10".to_owned()),
        Some("20".to_owned()),
    ];
    println!("{:?}", v);
    g(&mut v, "10");
    println!("{:?}", v);
    h(&mut v, "20");
    println!("{:?}", v);
}

输出:

[Some("10"), Some("5"), None, Some("20"), Some("10"), Some("20")]
[None, Some("5"), None, Some("20"), None, Some("20")]
[None, Some("5"), None, None, None, None]

Playground