hashmap_union/
lib.rs

1// from https://docs.rs/im/7.1.0/src/im/hashmap/mod.rs.html#584-590
2use std::hash::Hash;
3use std::collections::HashMap;
4
5/// Merges two hashmaps, using f where the keys exist in both hashmaps
6/// * one: The first hashmap
7/// * two: The second hashmap
8/// * f: What to do when the key exists in both hashmaps
9/// * Returns: The union of one and two
10pub fn union_of<K, V, F>(one: &HashMap<K, V>, two: &HashMap<K, V>, f: F) -> HashMap<K, V>
11where
12    K: Hash + Eq + Clone,
13    V: Clone,
14    F: Fn(V, V) -> V
15{
16    two
17        .iter()
18        .fold(one.clone(), |mut m: HashMap<K, V>, (k, v)| {
19                m.insert(
20                    k.clone(),
21                    one.get(k).map(|v1: &V| f(v1.clone(), v.clone())).unwrap_or(v.clone())
22                );
23                m
24            }
25        )
26}
27
28/// Gets the intersection of two HashMaps, using f to join them
29/// * one: The first hashmap
30/// * two: The second hashmap
31/// * f: What to do when the key exists in both hashmaps
32/// * Returns: The intersection of one and two
33pub fn intersection_of<K, A, B, C, F>(one: &HashMap<K, A>, two: &HashMap<K, B>, f: F) -> HashMap<K, C>
34where
35    K: Hash + Eq + Clone,
36    A: Clone,
37    B: Clone,
38    F: Fn(A, B) -> C
39{
40    let mut out = HashMap::new();
41    for (k, v2) in two {
42        match one.get(k) {
43            None => (),
44            Some(v1) => {
45                let result = f(v1.clone(), v2.clone());
46                out.insert(k.clone(), result);
47            }
48        }
49    }
50    out
51}