How to Filter a Vector of Custom Structs in Rust
This article is about filtering a vector of custom structs in Rust.
Rust Filter
A library for creating predicates and filters for use with the Iterator::filter
function. There are types and traits in this library that can be used to create filters and then combine them with logical operators such as AND
, OR
, NOT
, and others.
By implementing the Filter
trait, one can create custom filters. Though intended for use in the Iterator::filter()
function, the library can be used in other places, including other functions.
Example for rust filtering a vector:
let numbers: Vec<i32> = vec![
10, 20, 30, 40, 50, 60, 70, 80,
];
let even_number = numbers
.into_iter()
.filter(|n| n % 2 == 0)
.collect::<Vec<_>>();
println!("{:?}", even_number);
Output:
10, 20, 30, 40, 50, 60, 70, 80
Fix Vector of Custom Structs
by Filtering in Rust
-
The iteration over references should be swapped out for iteration over the actual values. The default option necessitates the fact that we are the owner of the vector.
Use
into_iter
instead ofiter
to create a loop.let the_words: Vec<Words> = words_context .vocabularies .into_iter() .filter(|voc| voc.metadata.identifier == words_id) .collect();
Else, we can
drain
the iterator if a mutable reference is present.let the_words: Vec<Words> = words_context .vocabularies .drain(..) .filter(|voc| voc.metadata.identifier == words_id) .collect();
-
Cloning the objects will allow you to duplicate them. This necessitates that the type you are iterating on implements the
Clone
method.It is recommended that you call
cloned()
immediately after filtering and before callingcollect()
to avoid cloning something that has been previously discarded.let the_words: Vec<Words> = words_context .vocabularies .iter() .filter(|voc| voc.metadata.identifier == words_id) .cloned() .collect();
-
It is better to collect a
Vec
of references rather than values. Therefore, the following is required: however you use the items after that, you must take an item by reference rather than by value.let the_words: Vec<&Words> = words_context .vocabularies .iter() .filter(|voc| voc.metadata.identifier == words_id) .collect();
It is only necessary to specify the type of the variable, or the word
collect
, not both at the same time.let the_ word: Vec_
could be used at the beginning of all three examples to allow the compiler to infer the type of data contained within the collection based on the iterator.