0

我想将 HashSet[0] 的元素移动到 HashSet[1]:

方案一:直接remove() insert()

错误,无法遵守。

use std::collections::HashSet;

fn main() {
    let mut hsets = vec![];

    // first set
    hsets.push(HashSet::new());
    hsets[0].insert("a1");
    hsets[0].insert("a2");

    // second set
    hsets.push(HashSet::new());
    hsets[1].insert("b1");
    hsets[1].insert("b2");

    // I want move elements of HashSet[0] to HashSet[1]
    for &v in hsets[0].iter() {
        hsets[0].remove(v);
        hsets[1].insert(v);
    }

    dbg!(&hsets);
}
error[E0502]: cannot borrow `hsets` as mutable because it is also borrowed as immutable
  --> src/main.rs:17:9
   |
16 |     for &v in hsets[0].iter() {
   |               ---------------
   |               |
   |               immutable borrow occurs here
   |               immutable borrow later used here
17 |         hsets[0].remove(v);
   |         ^^^^^ mutable borrow occurs here

error[E0502]: cannot borrow `hsets` as mutable because it is also borrowed as immutable
error: aborting due to 2 previous errors

项目2:使用tmp vec

正确,但需要额外的内存!其实我的hsets数据大小超过56G内存!所以我希望不要增加额外的内存。

use std::collections::HashSet;

fn main() {
    let mut hsets = vec![];

    // first set
    hsets.push(HashSet::new());
    hsets[0].insert("a1");
    hsets[0].insert("a2");

    // second set
    hsets.push(HashSet::new());
    hsets[1].insert("b1");
    hsets[1].insert("b2");

    let mut arr = vec![];
    for &v in hsets[0].iter() {
        arr.push(v);
    }
    for v in arr {
        hsets[0].remove(v);
        hsets[1].insert(v);
    }

    dbg!(&hsets);
}

项目 3:使用 split_at_mut()

正确,但我的 hsets vec 有数百万个元素。所以可能不是一个好方法。谢谢椒盐脆饼让路!

use std::collections::HashSet;

fn main() {
    let mut hsets = vec![];

    // first set
    hsets.push(HashSet::new());
    hsets[0].insert("a1");
    hsets[0].insert("a2");

    // second set
    hsets.push(HashSet::new());
    hsets[1].insert("b1");
    hsets[1].insert("b2");

    dbg!(&hsets);
    assert_eq!(hsets[0].len(), 2);
    assert_eq!(hsets[1].len(), 2);

    // move elements from first set to second set
    let (first, second) = hsets.split_at_mut(1);
    second[0].extend(first[0].drain());

    dbg!(&hsets);
    assert_eq!(hsets[0].len(), 0);
    assert_eq!(hsets[1].len(), 4);
}
4

1 回答 1

0

正确,但我的 hsets vec 有数百万个元素。所以可能不是一个好方法。谢谢

split*方法(split_at, split_first,和它们的split_last可变变体)只是返回切片和引用,它们在恒定时间内执行,它们不复制任何东西,它们当然不分配,所以 vec 的大小并不是真正的问题。

如果您有 10 个元素 vec 并在中间拆分,它将创建两个切片,它们引用原始向量并且长度为 5 和 5,如果您的向量有 1000 万个元素,则切片的长度为 5000000 和 5000000。实际差异。

于 2020-05-07T06:42:08.100 回答