anderspitman
anderspitman

Reputation: 10530

What's the best way to compare 2 vectors or strings element by element?

What's the best way to compare 2 vectors or strings element by element in Rust, while being able to do processing on each pair of elements? For example if you wanted to keep count of the number of differing elements. This is what I'm using:

let mut diff_count: i32 = 0i32;
for (x, y) in a.chars().zip(b.chars()) {
    if x != y {
        diff_count += 1i32;
    }
}

Is that the correct way or is there something more canonical?

Upvotes: 26

Views: 33108

Answers (2)

Shepmaster
Shepmaster

Reputation: 431669

To get the count of matching elements, I'd probably use filter and count.

fn main() {
    let a = "Hello";
    let b = "World";

    let matching = a.chars().zip(b.chars()).filter(|&(a, b)| a == b).count();
    println!("{}", matching);

    let a = [1, 2, 3, 4, 5];
    let b = [1, 1, 3, 3, 5];

    let matching = a.iter().zip(&b).filter(|&(a, b)| a == b).count();
    println!("{}", matching);
}
  • Iterator::zip takes two iterators and produces another iterator of the tuple of each iterator's values.
  • Iterator::filter takes a reference to the iterator's value and discards any value where the predicate closure returns false. This performs the comparison.
  • Iterator::count counts the number of elements in the iterator.

Note that Iterator::zip stops iterating when one iterator is exhausted. If you need different behavior, you may also be interested in Itertools::zip_longest or Itertools::zip_eq.

Upvotes: 37

Paul Chernoch
Paul Chernoch

Reputation: 5553

If you wanted to use @Shepmaster's answer as the basis of an assertion to be used in a unit test, try this:

fn do_vecs_match<T: PartialEq>(a: &Vec<T>, b: &Vec<T>) -> bool {
    let matching = a.iter().zip(b.iter()).filter(|&(a, b)| a == b).count();
    matching == a.len() && matching == b.len()
}

Of course, be careful when using this on floats! Those pesky NaNs won't compare, and you might want to use a tolerance for comparing the other values. And you might want to make it fancy by telling the index of the first nonmatching value.

Upvotes: 11

Related Questions