use std::{collections::HashSet, hash::Hash};
use itertools::izip;
fn set_overlap<T: Hash + Eq>(aset: &HashSet<T>, bset: &HashSet<T>) -> bool {
for el in aset {
if bset.contains(el) {
return true;
}
}
false
}
fn set_intersection<T: Hash + Eq + Clone>(a: &HashSet<T>, b: &HashSet<T>) -> HashSet<T> {
a.intersection(b).cloned().collect()
}
pub struct Intersector<T, S> {
pub keys: Vec<HashSet<T>>,
pub items: Vec<Vec<S>>,
}
impl<T: Hash + Eq + Clone, S> Intersector<T, S> {
pub fn new() -> Self {
Intersector { keys: Vec::new(), items: Vec::new() }
}
pub fn iterate_items(&self) -> impl Iterator<Item = (&HashSet<T>, &Vec<S>)> {
izip!(&self.keys, &self.items)
}
fn find_overlap_ix(&self, set: &HashSet<T>) -> Option<usize> {
for (i, k) in self.keys.iter().enumerate() {
if set_overlap(k, set) {
return Some(i);
}
}
None
}
pub fn add(&mut self, set: HashSet<T>, item: S) {
match self.find_overlap_ix(&set) {
Some(i) => {
let old_key = self.keys.remove(i);
let mut old_items = self.items.remove(i);
let update_key = set_intersection(&old_key, &set);
old_items.push(item);
self.keys.push(update_key);
self.items.push(old_items);
}
None => {
self.keys.push(set);
self.items.push(vec![item]);
}
}
}
}
#[cfg(test)]
mod testing {
use crate::{disjoint::Intersector, utils::vec2set};
#[test]
fn test_inter() {
let mut it: Intersector<String, usize> = Intersector::new();
let k1 = vec2set(vec!["A".to_string()]);
let k2 = vec2set(vec!["B".to_string()]);
it.add(k1, 1);
it.add(k2, 2);
println!("{:?}", it.items);
assert_eq!(it.keys.len(), 2);
let mut it: Intersector<String, usize> = Intersector::new();
let k1 = vec2set(vec!["A".to_string()]);
let k2 = vec2set(vec!["A".to_string(), "B".to_string()]);
it.add(k1, 1);
it.add(k2, 2);
println!("{:?}", it.items);
assert_eq!(it.keys.len(), 1);
assert_eq!(it.keys, vec![vec2set(vec!["A".to_string()]),]);
let mut it: Intersector<String, usize> = Intersector::new();
let k1 = vec2set(vec!["A".to_string(), "B".to_string()]);
let k2 = vec2set(vec!["A".to_string()]);
let k3 = vec2set(vec!["C".to_string()]);
it.add(k1, 1);
it.add(k2, 2);
it.add(k3, 3);
println!("{:?}", it.items);
assert_eq!(it.keys.len(), 2);
assert_eq!(
it.keys,
vec![
vec2set(vec!["A".to_string()]),
vec2set(vec!["C".to_string()]),
]
);
}
}