代码之家  ›  专栏  ›  技术社区  ›  Jeffrey04 George

是否有方法从另一个向量中存在的通用第一个向量中删除条目?

  •  0
  • Jeffrey04 George  · 技术社区  · 6 年前

    当调用高阶函数时,我无法理解所有权。如果元素存在于第二个向量中,我应该从第一个向量中删除条目,因此我提出了以下尝试:

    fn array_diff<T: PartialEq>(a: Vec<T>, b: Vec<T>) -> Vec<T> {
        a.iter()
            .filter(|incoming| !b.contains(incoming))
            .collect::<Vec<T>>()
    }
    

    我无法更改函数签名。这个 .collect() 调用不起作用,因为我得到的只是对中元素的引用 a . 虽然这是通用的,但我不知道结果是不是 copy -有能力或 clone -有能力。我也可能无法取消引用 .

    有没有办法在不从头重写的情况下修复这段代码?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Simon Whitehead    6 年前

    对于这个特殊的测试…您可以使用向量而不是依赖引用。签名生成值,而不是引用。因此,要通过考试,你只需使用 into_iter 相反:

    a.into_iter() // <----------- call into_iter
        .filter(|incoming| !b.contains(incoming))
        .collect::<Vec<T>>()
    

    这将消耗这些值并再次返回。

        2
  •  0
  •   Shepmaster Lukas Kalbertodt    6 年前

    销毁传入的分配以创建新的分配不是很有效。相反,编写更直接符合问题语句的代码:

    fn array_diff<T: PartialEq>(mut a: Vec<T>, b: Vec<T>) -> Vec<T> {
        a.retain(|aa| !b.contains(aa));
        a
    }
    

    添加 mut 在签名中 不更改签名 因为没人知道你添加了它。与以下内容完全相同:

    fn array_diff<T: PartialEq>(a: Vec<T>, b: Vec<T>) -> Vec<T> {
        let mut a = a;
        a.retain(|aa| !b.contains(aa));
        a
    }