Есть ли способ удалить записи из общего первого вектора, которые присутствуют в другом векторе? - PullRequest
0 голосов
/ 03 июля 2018

У меня проблема с пониманием владения, когда вызывается функция более высокого порядка. Я должен удалить записи из первого вектора, если элементы существуют во втором векторе, поэтому я предпринял эту попытку:

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. Я также, вероятно, не могу разыменовать элементы в a.

Есть ли способ исправить этот кусок кода, не переписывая его с нуля?

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Уничтожение входящего выделения для создания нового распределения не очень эффективно. Вместо этого напишите код, который более точно соответствует формулировке проблемы:

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
}
0 голосов
/ 03 июля 2018

Для этого конкретного теста ... вы можете использовать вектор вместо ссылок. Подпись дает значения, а не ссылки. Таким образом, чтобы пройти тест, вам нужно использовать into_iter вместо:

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

Это потребляет значения и возвращает их снова.

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