About borrow and move

use std::collections::HashMap;

struct Solution;

impl Solution {
    pub fn has_groups_size_x(deck: Vec<i32>) -> bool {
        let mut map: HashMap<i32, i32> = HashMap::new();
        for d in deck {
            if let Some(x) = map.get_mut(&d) {
                *x += 1;
            } else {
                map.insert(d, 1);
            }
        }
        let odds: Vec<i32> = map.values().filter(|&x| x & 1 != 0).map(|&x| x).collect();
        if odds.is_empty() {
            return true;
        }
        let len = odds.len();
        let m = odds.into_iter().min().unwrap();
        for i in 0..len {
            if odds[i] % m != 0 {
                return false;
            }
        }
        true
    }
}

After using odds.into_iter(), odds[i] caused error of value borrowed here after move.
How to understand and fix it?

Use iter instead of into_iter, that way you borrow the vec instead of taking ownership of the vec.

That works.

    let m = odds.iter().min().unwrap();
    for i in odds {
        if i % m != 0 {
            return false;
        }
    }

why does this get errors?

Because m is &i32, so odds is still borrowed here. .iter() produces an Iterator of shared references. To avoid it, you can use .copied() iterator adapter which is identical to .map(|&x| x), but more idiomatic.

So, what's idiomatic codes to cope with this problem here?

    let &m = odds.iter().min().unwrap();
    // or
    let m = *odds.iter().min().unwrap();
    // or
    let m = odds.iter().min().copied().unwrap();

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.