Skip to content

Commit 99eb4dd

Browse files
committed
add difference and symmetric_difference to Set
1 parent 42cafce commit 99eb4dd

File tree

3 files changed

+88
-17
lines changed

3 files changed

+88
-17
lines changed

src/libcore/container.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,10 @@ pub trait Set<T>: Mutable {
7575

7676
/// Return true if the set is a superset of another
7777
pure fn is_superset(&self, other: &self) -> bool;
78+
79+
/// Visit the values representing the difference
80+
pure fn difference(&self, other: &self, f: fn(&T) -> bool);
81+
82+
/// Visit the values representing the symmetric difference
83+
pure fn symmetric_difference(&self, other: &self, f: fn(&T) -> bool);
7884
}

src/libcore/hashmap.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,22 @@ pub mod linear {
469469
pure fn is_superset(&self, other: &LinearSet<T>) -> bool {
470470
other.is_subset(self)
471471
}
472+
473+
/// Visit the values representing the difference
474+
pure fn difference(&self, other: &LinearSet<T>, f: fn(&T) -> bool) {
475+
for self.each |v| {
476+
if !other.contains(v) {
477+
if !f(v) { return; }
478+
}
479+
}
480+
}
481+
482+
/// Visit the values representing the symmetric difference
483+
pure fn symmetric_difference(&self, other: &LinearSet<T>,
484+
f: fn(&T) -> bool) {
485+
self.difference(other, f);
486+
other.difference(self, f);
487+
}
472488
}
473489

474490
pub impl <T: Hash IterBytes Eq> LinearSet<T> {
@@ -681,4 +697,53 @@ mod test_set {
681697
assert !b.is_subset(&a);
682698
assert b.is_superset(&a);
683699
}
700+
701+
#[test]
702+
fn test_difference() {
703+
let mut a = linear::LinearSet::new();
704+
let mut b = linear::LinearSet::new();
705+
706+
assert a.insert(1);
707+
assert a.insert(3);
708+
assert a.insert(5);
709+
assert a.insert(9);
710+
assert a.insert(11);
711+
712+
assert b.insert(3);
713+
assert b.insert(9);
714+
715+
let mut i = 0;
716+
let expected = [1, 5, 11];
717+
for a.difference(&b) |x| {
718+
assert vec::contains(expected, x);
719+
i += 1
720+
}
721+
assert i == expected.len();
722+
}
723+
724+
#[test]
725+
fn test_symmetric_difference() {
726+
let mut a = linear::LinearSet::new();
727+
let mut b = linear::LinearSet::new();
728+
729+
assert a.insert(1);
730+
assert a.insert(3);
731+
assert a.insert(5);
732+
assert a.insert(9);
733+
assert a.insert(11);
734+
735+
assert b.insert(-2);
736+
assert b.insert(3);
737+
assert b.insert(9);
738+
assert b.insert(14);
739+
assert b.insert(22);
740+
741+
let mut i = 0;
742+
let expected = [-2, 1, 5, 11, 14, 22];
743+
for a.symmetric_difference(&b) |x| {
744+
assert vec::contains(expected, x);
745+
i += 1
746+
}
747+
assert i == expected.len();
748+
}
684749
}

src/libstd/treemap.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ use core::prelude::*;
2929
// range search - O(log n) retrieval of an iterator from some key
3030

3131
// (possibly) implement the overloads Python does for sets:
32-
// * union: |
3332
// * intersection: &
3433
// * difference: -
3534
// * symmetric difference: ^
35+
// * union: |
3636
// These would be convenient since the methods work like `each`
3737

3838
pub struct TreeMap<K, V> {
@@ -355,22 +355,6 @@ impl <T: Ord> TreeSet<T>: Set<T> {
355355
}
356356
true
357357
}
358-
}
359-
360-
impl <T: Ord> TreeSet<T> {
361-
/// Create an empty TreeSet
362-
static pure fn new() -> TreeSet<T> { TreeSet{map: TreeMap::new()} }
363-
364-
/// Visit all values in reverse order
365-
pure fn each_reverse(&self, f: fn(&T) -> bool) {
366-
self.map.each_key_reverse(f)
367-
}
368-
369-
/// Get a lazy iterator over the values in the set.
370-
/// Requires that it be frozen (immutable).
371-
pure fn iter(&self) -> TreeSetIterator/&self<T> {
372-
TreeSetIterator{iter: self.map.iter()}
373-
}
374358

375359
/// Visit the values (in-order) representing the difference
376360
pure fn difference(&self, other: &TreeSet<T>, f: fn(&T) -> bool) {
@@ -448,6 +432,22 @@ impl <T: Ord> TreeSet<T> {
448432
}
449433
}
450434
}
435+
}
436+
437+
impl <T: Ord> TreeSet<T> {
438+
/// Create an empty TreeSet
439+
static pure fn new() -> TreeSet<T> { TreeSet{map: TreeMap::new()} }
440+
441+
/// Visit all values in reverse order
442+
pure fn each_reverse(&self, f: fn(&T) -> bool) {
443+
self.map.each_key_reverse(f)
444+
}
445+
446+
/// Get a lazy iterator over the values in the set.
447+
/// Requires that it be frozen (immutable).
448+
pure fn iter(&self) -> TreeSetIterator/&self<T> {
449+
TreeSetIterator{iter: self.map.iter()}
450+
}
451451

452452
/// Visit the values (in-order) representing the intersection
453453
pure fn intersection(&self, other: &TreeSet<T>, f: fn(&T) -> bool) {

0 commit comments

Comments
 (0)