1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
use std::collections::HashMap;
pub fn merge<T, O, K, F, X, Y>(
this: &mut std::vec::Vec<T>,
mut other: Vec<O>,
tkey: X,
okey: Y,
assign: F,
) where
O: Clone,
K: Eq + std::hash::Hash,
F: Fn(&mut T, O),
X: Fn(&T) -> Option<K>,
Y: Fn(&O) -> Option<K>,
{
let mut index: HashMap<K, Vec<usize>> = HashMap::new();
for (i, b) in this.iter().enumerate() {
match tkey(&b) {
Some(k) => {
let v = index.entry(k).or_insert(Vec::new());
v.push(i);
}
None => {}
}
}
for a in other.drain(..) {
match &okey(&a) {
Some(ok) => {
let vbi = index.get(ok).unwrap();
for bi in vbi.iter().skip(1) {
if let Some(mut b) = this.get_mut(*bi) {
assign(&mut b, a.clone());
}
}
let fbi = vbi.get(0).unwrap();
if let Some(mut b) = this.get_mut(*fbi) {
assign(&mut b, a.clone());
}
}
None => {}
}
}
}