How to Filter a Vector of Custom Structs in Rust

Nilesh Katuwal Feb 02, 2024
  1. Rust Filter
  2. Fix Vector of Custom Structs by Filtering in Rust
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

  1. 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 of iter 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();
    
  1. 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 calling collect() 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();
    
  2. 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.