add difference and symmetric_difference to Set

This commit is contained in:
Daniel Micay 2013-01-29 19:30:26 -05:00
parent 42cafcee2c
commit 99eb4ddddd
3 changed files with 88 additions and 17 deletions

View file

@ -75,4 +75,10 @@ pub trait Set<T>: Mutable {
/// Return true if the set is a superset of another
pure fn is_superset(&self, other: &self) -> bool;
/// Visit the values representing the difference
pure fn difference(&self, other: &self, f: fn(&T) -> bool);
/// Visit the values representing the symmetric difference
pure fn symmetric_difference(&self, other: &self, f: fn(&T) -> bool);
}

View file

@ -469,6 +469,22 @@ pub mod linear {
pure fn is_superset(&self, other: &LinearSet<T>) -> bool {
other.is_subset(self)
}
/// Visit the values representing the difference
pure fn difference(&self, other: &LinearSet<T>, f: fn(&T) -> bool) {
for self.each |v| {
if !other.contains(v) {
if !f(v) { return; }
}
}
}
/// Visit the values representing the symmetric difference
pure fn symmetric_difference(&self, other: &LinearSet<T>,
f: fn(&T) -> bool) {
self.difference(other, f);
other.difference(self, f);
}
}
pub impl <T: Hash IterBytes Eq> LinearSet<T> {
@ -681,4 +697,53 @@ mod test_set {
assert !b.is_subset(&a);
assert b.is_superset(&a);
}
#[test]
fn test_difference() {
let mut a = linear::LinearSet::new();
let mut b = linear::LinearSet::new();
assert a.insert(1);
assert a.insert(3);
assert a.insert(5);
assert a.insert(9);
assert a.insert(11);
assert b.insert(3);
assert b.insert(9);
let mut i = 0;
let expected = [1, 5, 11];
for a.difference(&b) |x| {
assert vec::contains(expected, x);
i += 1
}
assert i == expected.len();
}
#[test]
fn test_symmetric_difference() {
let mut a = linear::LinearSet::new();
let mut b = linear::LinearSet::new();
assert a.insert(1);
assert a.insert(3);
assert a.insert(5);
assert a.insert(9);
assert a.insert(11);
assert b.insert(-2);
assert b.insert(3);
assert b.insert(9);
assert b.insert(14);
assert b.insert(22);
let mut i = 0;
let expected = [-2, 1, 5, 11, 14, 22];
for a.symmetric_difference(&b) |x| {
assert vec::contains(expected, x);
i += 1
}
assert i == expected.len();
}
}

View file

@ -29,10 +29,10 @@ use core::prelude::*;
// range search - O(log n) retrieval of an iterator from some key
// (possibly) implement the overloads Python does for sets:
// * union: |
// * intersection: &
// * difference: -
// * symmetric difference: ^
// * union: |
// These would be convenient since the methods work like `each`
pub struct TreeMap<K, V> {
@ -355,22 +355,6 @@ impl <T: Ord> TreeSet<T>: Set<T> {
}
true
}
}
impl <T: Ord> TreeSet<T> {
/// Create an empty TreeSet
static pure fn new() -> TreeSet<T> { TreeSet{map: TreeMap::new()} }
/// Visit all values in reverse order
pure fn each_reverse(&self, f: fn(&T) -> bool) {
self.map.each_key_reverse(f)
}
/// Get a lazy iterator over the values in the set.
/// Requires that it be frozen (immutable).
pure fn iter(&self) -> TreeSetIterator/&self<T> {
TreeSetIterator{iter: self.map.iter()}
}
/// Visit the values (in-order) representing the difference
pure fn difference(&self, other: &TreeSet<T>, f: fn(&T) -> bool) {
@ -448,6 +432,22 @@ impl <T: Ord> TreeSet<T> {
}
}
}
}
impl <T: Ord> TreeSet<T> {
/// Create an empty TreeSet
static pure fn new() -> TreeSet<T> { TreeSet{map: TreeMap::new()} }
/// Visit all values in reverse order
pure fn each_reverse(&self, f: fn(&T) -> bool) {
self.map.each_key_reverse(f)
}
/// Get a lazy iterator over the values in the set.
/// Requires that it be frozen (immutable).
pure fn iter(&self) -> TreeSetIterator/&self<T> {
TreeSetIterator{iter: self.map.iter()}
}
/// Visit the values (in-order) representing the intersection
pure fn intersection(&self, other: &TreeSet<T>, f: fn(&T) -> bool) {