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

Multi tool use
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?





question originally from codewars codewars.com/kata/array-dot-diff/train/rust
– Jeffrey04
Jul 3 at 4:01





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.

Efw8nh
mj,BR9tTPND4yu7u M6U L5XW7cNMbO01N,JY8bw,me Q0TizRquNop

Popular posts from this blog

PHP contact form sending but not receiving emails

Do graphics cards have individual ID by which single devices can be distinguished?

Create weekly swift ios local notifications