Возможно ли вообще объединить векторы в Rust? Если да, то есть ли элегантный способ сделать это? У меня примерно так:

let mut a = vec![1, 2, 3];
let b = vec![4, 5, 6];

for val in &b {
    a.push(val);
}

Кто-нибудь знает способ лучше?

Joe Thomas

Ответов: 3

Ответы (3)

Структура std :: vec :: Vec имеет метод append ():

fn append(&mut self, other: &mut Vec)

Перемещает все элементы из other в Self, оставляя other пустым.

Из вашего примера следующий код объединит два вектора путем изменения a и b:

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

    a.append(&mut b);

    assert_eq!(a, [1, 2, 3, 4, 5, 6]);
    assert_eq!(b, []);
}

В качестве альтернативы вы можете использовать Extend :: extend (), чтобы добавить все элементы чего-то, что можно превратить в итератор (например, Vec), в заданный вектор:

let mut a = vec![1, 2, 3];
let b = vec![4, 5, 6];

a.extend(b);
assert_eq!(a, [1, 2, 3, 4, 5, 6]);
// b is moved and can't be used anymore

Обратите внимание, что вектор b перемещается, а не очищается. Если ваши векторы содержат элементы, реализующие Copy, вы можете вместо этого передать неизменяемую ссылку на один вектор в extend (), чтобы избежать перемещения. В этом случае вектор b не меняется:

let mut a = vec![1, 2, 3];
let b = vec![4, 5, 6];

a.extend(&b);
assert_eq!(a, [1, 2, 3, 4, 5, 6]);
assert_eq!(b, [4, 5, 6]);

Что касается производительности, slice :: concat, append и extend примерно одинаковы. Если вам не нужны результаты сразу, сделайте его цепным итератором - это самый быстрый способ; если вам нужно collect (), это самый медленный:

#! [Функция (тест)]

тест внешней обрешетки;

используйте test :: Bencher;

#[скамейка]
fn bench_concat ___ init __ (b: & mut Bencher) {
    b.iter (|| {
        пусть mut x = vec! [1i32; 100000];
        пусть mut y = vec! [2i32; 100000];
    });
}

#[скамейка]
fn bench_concat_append (b: & mut Bencher) {
    b.iter (|| {
        пусть mut x = vec! [1i32; 100000];
        пусть mut y = vec! [2i32; 100000];
        x.append (& mut y)
    });
}

#[скамейка]
fn bench_concat_extend (b: & mut Bencher) {
    b.iter (|| {
        пусть mut x = vec! [1i32; 100000];
        пусть mut y = vec! [2i32; 100000];
        x.extend (y)
    });
}

#[скамейка]
fn bench_concat_concat (b: & mut Bencher) {
    b.iter (|| {
        пусть mut x = vec! [1i32; 100000];
        пусть mut y = vec! [2i32; 100000];
        [x, y] .concat ()
    });
}

#[скамейка]
fn bench_concat_iter_chain (b: & mut Bencher) {
    b.iter (|| {
        пусть mut x = vec! [1i32; 100000];
        пусть mut y = vec! [2i32; 100000];
        x.into_iter (). цепочка (y.into_iter ())
    });
}

#[скамейка]
fn bench_concat_iter_chain_collect (b: & mut Bencher) {
    b.iter (|| {
        пусть mut x = vec! [1i32; 100000];
        пусть mut y = vec! [2i32; 100000];
        x.into_iter (). chain (y.into_iter ()). collect :: > ()
    });
}
running 6 tests
test bench_concat___init__           ... bench:      27,261 ns/iter (+/- 3,129)
test bench_concat_append             ... bench:      52,820 ns/iter (+/- 9,243)
test bench_concat_concat             ... bench:      53,566 ns/iter (+/- 5,748)
test bench_concat_extend             ... bench:      53,920 ns/iter (+/- 7,329)
test bench_concat_iter_chain         ... bench:      26,901 ns/iter (+/- 1,306)
test bench_concat_iter_chain_collect ... bench:     190,334 ns/iter (+/- 16,107)

Я не могу сделать это в одну строчку.Дамиан Дзядуч

Это можно сделать одной строкой, используя chain ():

пусть c: Vec  = a.into_iter (). Chain (b.into_iter ()). Collect (); // Потреблено
пусть c: Vec <& i32> = a.iter (). chain (b.iter ()). collect (); // Ссылка
пусть c: Vec  = a.iter (). cloned (). chain (b.iter (). cloned ()). collect (); // Клонировано
пусть c: Vec  = a.iter (). copied (). chain (b.iter (). copied ()). collect (); // Скопировано

Есть бесконечное количество способов.

2022 WebDevInsider