Is there a way to remove entries from a generic first vector that are present in another vector?

Multi tool use
Is there a way to remove entries from a generic first vector that are present in another vector?
I have a problem understanding ownership when a higher order function is called. I am supposed to remove entries from the first vector if the elements exist in the second vector so I came up with this attempt:
fn array_diff<T: PartialEq>(a: Vec<T>, b: Vec<T>) -> Vec<T> {
a.iter()
.filter(|incoming| !b.contains(incoming))
.collect::<Vec<T>>()
}
I can't change the function signature. The .collect()
call doesn't work because all I am getting is a reference to elements in a
. While this is generic, I don't know if the result is copy
-able or clone
-able. I also probably can't dereference the elements in a
.
.collect()
a
copy
clone
a
Is there a way to fix this piece of code without rewriting it from scratch?
Why
collect
gets references? Hint, look at iter
. Another hint: into_iter
.– red75prime
Jul 3 at 4:50
collect
iter
into_iter
wasn't aware there's
into_iter
and wasn't aware iter
returns reference #facepalm thanks for the tip– Jeffrey04
Jul 3 at 4:58
into_iter
iter
2 Answers
2
For this particular test ... you can consume the vector instead of relying on references. The signature yields values and not references. As such, to pass the test you only have to use into_iter
instead:
into_iter
a.into_iter() // <----------- call into_iter
.filter(|incoming| !b.contains(incoming))
.collect::<Vec<T>>()
This consumes the values and returns them out again.
LOL, OK i need to spend some time reading the documentation. I didn't know the function exists (got the
iter
from official guide lol).– Jeffrey04
Jul 3 at 4:57
iter
Destroying the incoming allocation to create a new allocation isn't very efficient. Instead, write code that is more directly in line with the problem statement:
fn array_diff<T: PartialEq>(mut a: Vec<T>, b: Vec<T>) -> Vec<T> {
a.retain(|aa| !b.contains(aa));
a
}
Adding mut
in the signature doesn't change the signature because no one can tell that you've added it. It's the exact same as:
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
}
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
question originally from codewars codewars.com/kata/array-dot-diff/train/rust
– Jeffrey04
Jul 3 at 4:01