add intersection and union to the Set trait
This commit is contained in:
parent
99eb4ddddd
commit
6b08683e15
3 changed files with 105 additions and 17 deletions
|
@ -81,4 +81,10 @@ pub trait Set<T>: Mutable {
|
|||
|
||||
/// Visit the values representing the symmetric difference
|
||||
pure fn symmetric_difference(&self, other: &self, f: fn(&T) -> bool);
|
||||
|
||||
/// Visit the values representing the intersection
|
||||
pure fn intersection(&self, other: &self, f: fn(&T) -> bool);
|
||||
|
||||
/// Visit the values representing the union
|
||||
pure fn union(&self, other: &self, f: fn(&T) -> bool);
|
||||
}
|
||||
|
|
|
@ -474,7 +474,7 @@ pub mod linear {
|
|||
pure fn difference(&self, other: &LinearSet<T>, f: fn(&T) -> bool) {
|
||||
for self.each |v| {
|
||||
if !other.contains(v) {
|
||||
if !f(v) { return; }
|
||||
if !f(v) { return }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -485,6 +485,28 @@ pub mod linear {
|
|||
self.difference(other, f);
|
||||
other.difference(self, f);
|
||||
}
|
||||
|
||||
/// Visit the values representing the intersection
|
||||
pure fn intersection(&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 union
|
||||
pure fn union(&self, other: &LinearSet<T>, f: fn(&T) -> bool) {
|
||||
for self.each |v| {
|
||||
if !f(v) { return }
|
||||
}
|
||||
|
||||
for other.each |v| {
|
||||
if !self.contains(v) {
|
||||
if !f(v) { return }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub impl <T: Hash IterBytes Eq> LinearSet<T> {
|
||||
|
@ -698,6 +720,36 @@ mod test_set {
|
|||
assert b.is_superset(&a);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intersection() {
|
||||
let mut a = linear::LinearSet::new();
|
||||
let mut b = linear::LinearSet::new();
|
||||
|
||||
assert a.insert(11);
|
||||
assert a.insert(1);
|
||||
assert a.insert(3);
|
||||
assert a.insert(77);
|
||||
assert a.insert(103);
|
||||
assert a.insert(5);
|
||||
assert a.insert(-5);
|
||||
|
||||
assert b.insert(2);
|
||||
assert b.insert(11);
|
||||
assert b.insert(77);
|
||||
assert b.insert(-9);
|
||||
assert b.insert(-42);
|
||||
assert b.insert(5);
|
||||
assert b.insert(3);
|
||||
|
||||
let mut i = 0;
|
||||
let expected = [3, 5, 11, 77];
|
||||
for a.intersection(&b) |x| {
|
||||
assert vec::contains(expected, x);
|
||||
i += 1
|
||||
}
|
||||
assert i == expected.len();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_difference() {
|
||||
let mut a = linear::LinearSet::new();
|
||||
|
@ -746,4 +798,34 @@ mod test_set {
|
|||
}
|
||||
assert i == expected.len();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_union() {
|
||||
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 a.insert(16);
|
||||
assert a.insert(19);
|
||||
assert a.insert(24);
|
||||
|
||||
assert b.insert(-2);
|
||||
assert b.insert(1);
|
||||
assert b.insert(5);
|
||||
assert b.insert(9);
|
||||
assert b.insert(13);
|
||||
assert b.insert(19);
|
||||
|
||||
let mut i = 0;
|
||||
let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
|
||||
for a.union(&b) |x| {
|
||||
assert vec::contains(expected, x);
|
||||
i += 1
|
||||
}
|
||||
assert i == expected.len();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -432,22 +432,6 @@ impl <T: Ord> TreeSet<T>: Set<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) {
|
||||
|
@ -516,6 +500,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()}
|
||||
}
|
||||
}
|
||||
|
||||
/// Lazy forward iterator over a set
|
||||
pub struct TreeSetIterator<T> {
|
||||
priv iter: TreeMapIterator<T, ()>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue