Как извлечь элементы вектора строк в Rust? - PullRequest
2 голосов
/ 08 марта 2019

Допустим, у меня есть следующий код :

fn extract() -> Vec<String> {
    let data = vec!["aaa".to_string(), "bbb".to_string(), "ccc".to_string()];
    vec![data[0], data[2]]
}

На практике я читаю data из файла.

Очевидно, это не компилируется, потому что я вытаскиваю строки из вектора data, оставляя вектор в неопределенном состоянии. Но, концептуально, это должно работать, потому что я все равно не буду использовать data впоследствии.

Я могу использовать mem::replace, но это кажется сумасшедшим:

fn extract() -> Vec<String> {
    let mut data = vec!["aaa".to_string(), "bbb".to_string(), "ccc".to_string()];
    let a = mem::replace(&mut data[0], "".to_string());
    let c = mem::replace(&mut data[2], "".to_string());
    vec![a, c]
}

Как мне извлечь определенные элементы из вектора без клонирования строк?

Ответы [ 2 ]

4 голосов
/ 08 марта 2019

Vec имеет специальные методы для этого. swap_remove, remove (предупреждение, линейная сложность), drain. Например,

fn extract() -> Vec<String> {
    let mut data = vec!["aaa".to_string(), "bbb".to_string(), "ccc".to_string()];
    // order does matter
    vec![data.swap_remove(2), data.swap_remove(0)]
}
1 голос
/ 08 марта 2019

Вы не можете иметь «дыры» в векторе. Поэтому, когда вы перемещаете что-то из этого, вы либо изменяете индексы оставшихся элементов (используя remove или swap_remove), либо заменяете это чем-то другим.

Почему бы вам просто не использовать вектор по порядку и игнорировать то, что вам не нужно? Если вам нужно сохранить некоторые элементы для последующего использования, вы можете использовать data.iter().filter(...).collect(). Если вы действительно хотите избежать копирования каких-либо строк, вы можете заключить их в Rc, чтобы копировались только указатели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...