Skip to content

Instantly share code, notes, and snippets.

@daltonclaybrook
Created February 1, 2020 19:25
Show Gist options
  • Save daltonclaybrook/1f9fce2b66a5ba13e55cfb66d48655c4 to your computer and use it in GitHub Desktop.
Save daltonclaybrook/1f9fce2b66a5ba13e55cfb66d48655c4 to your computer and use it in GitHub Desktop.
/// Types that implement this trait provide the rules
/// for replacing objects of the same type.
pub trait Replaceable {
type Key: Eq;
fn unique_key(&self) -> Self::Key;
fn should_replace(&self, other: &Self) -> bool;
}
/// Trait implemented for collections that can be
/// filtered using replacement rules
pub trait ReplacementFiltering {
fn filter_and_replace(self) -> Self;
}
/// Implementation of replacement filtering on Vec
impl<T> ReplacementFiltering for Vec<T> where T: Replaceable {
fn filter_and_replace(self) -> Self {
let mut result: Vec<T> = vec![];
for next in self {
match result.iter().enumerate().find(|(_, e)| (*e).unique_key() == next.unique_key()) {
Some((index, existing)) => {
if next.should_replace(existing) {
result.remove(index);
result.insert(index, next);
}
},
None => result.push(next)
}
}
result
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment