Skip to content

Commit d2befa1

Browse files
authored
Merge pull request #89 from AljoschaMeyer/master
Add relative_complement and symmetric_difference
2 parents c0a8fc6 + f519c66 commit d2befa1

File tree

4 files changed

+318
-18
lines changed

4 files changed

+318
-18
lines changed

src/hash/map.rs

Lines changed: 108 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -978,9 +978,12 @@ where
978978
.fold(Self::default(), |a, b| a.union_with_key(b, &f))
979979
}
980980

981-
/// Construct the difference between two maps by discarding keys
981+
/// Construct the symmetric difference between two maps by discarding keys
982982
/// which occur in both maps.
983983
///
984+
/// This is an alias for the
985+
/// [`symmetric_difference`][symmetric_difference] method.
986+
///
984987
/// Time: O(n log n)
985988
///
986989
/// # Examples
@@ -998,26 +1001,69 @@ where
9981001
#[inline]
9991002
#[must_use]
10001003
pub fn difference(self, other: Self) -> Self {
1001-
self.difference_with_key(other, |_, _, _| None)
1004+
self.symmetric_difference(other)
1005+
}
1006+
1007+
/// Construct the symmetric difference between two maps by discarding keys
1008+
/// which occur in both maps.
1009+
///
1010+
/// Time: O(n log n)
1011+
///
1012+
/// # Examples
1013+
///
1014+
/// ```
1015+
/// # #[macro_use] extern crate im;
1016+
/// # use im::hashmap::HashMap;
1017+
/// # fn main() {
1018+
/// let map1 = hashmap!{1 => 1, 3 => 4};
1019+
/// let map2 = hashmap!{2 => 2, 3 => 5};
1020+
/// let expected = hashmap!{1 => 1, 2 => 2};
1021+
/// assert_eq!(expected, map1.symmetric_difference(map2));
1022+
/// # }
1023+
/// ```
1024+
#[inline]
1025+
#[must_use]
1026+
pub fn symmetric_difference(self, other: Self) -> Self {
1027+
self.symmetric_difference_with_key(other, |_, _, _| None)
1028+
}
1029+
1030+
/// Construct the symmetric difference between two maps by using a function
1031+
/// to decide what to do if a key occurs in both.
1032+
///
1033+
/// This is an alias for the
1034+
/// [`symmetric_difference_with`][symmetric_difference_with] method.
1035+
///
1036+
/// Time: O(n log n)
1037+
#[inline]
1038+
#[must_use]
1039+
pub fn difference_with<F>(self, other: Self, f: F) -> Self
1040+
where
1041+
F: FnMut(V, V) -> Option<V>,
1042+
{
1043+
self.symmetric_difference_with(other, f)
10021044
}
10031045

1004-
/// Construct the difference between two maps by using a function
1046+
/// Construct the symmetric difference between two maps by using a function
10051047
/// to decide what to do if a key occurs in both.
10061048
///
10071049
/// Time: O(n log n)
10081050
#[inline]
10091051
#[must_use]
1010-
pub fn difference_with<F>(self, other: Self, mut f: F) -> Self
1052+
pub fn symmetric_difference_with<F>(self, other: Self, mut f: F) -> Self
10111053
where
10121054
F: FnMut(V, V) -> Option<V>,
10131055
{
1014-
self.difference_with_key(other, |_, a, b| f(a, b))
1056+
self.symmetric_difference_with_key(other, |_, a, b| f(a, b))
10151057
}
10161058

1017-
/// Construct the difference between two maps by using a function
1059+
/// Construct the symmetric difference between two maps by using a function
10181060
/// to decide what to do if a key occurs in both. The function
10191061
/// receives the key as well as both values.
10201062
///
1063+
/// This is an alias for the
1064+
/// [`symmetric_difference_with`_key][symmetric_difference_with_key]
1065+
/// method.
1066+
///
10211067
/// Time: O(n log n)
10221068
///
10231069
/// # Examples
@@ -1036,7 +1082,36 @@ where
10361082
/// # }
10371083
/// ```
10381084
#[must_use]
1039-
pub fn difference_with_key<F>(mut self, other: Self, mut f: F) -> Self
1085+
pub fn difference_with_key<F>(self, other: Self, f: F) -> Self
1086+
where
1087+
F: FnMut(&K, V, V) -> Option<V>,
1088+
{
1089+
self.symmetric_difference_with_key(other, f)
1090+
}
1091+
1092+
/// Construct the symmetric difference between two maps by using a function
1093+
/// to decide what to do if a key occurs in both. The function
1094+
/// receives the key as well as both values.
1095+
///
1096+
/// Time: O(n log n)
1097+
///
1098+
/// # Examples
1099+
///
1100+
/// ```
1101+
/// # #[macro_use] extern crate im;
1102+
/// # use im::hashmap::HashMap;
1103+
/// # fn main() {
1104+
/// let map1 = hashmap!{1 => 1, 3 => 4};
1105+
/// let map2 = hashmap!{2 => 2, 3 => 5};
1106+
/// let expected = hashmap!{1 => 1, 2 => 2, 3 => 9};
1107+
/// assert_eq!(expected, map1.symmetric_difference_with_key(
1108+
/// map2,
1109+
/// |key, left, right| Some(left + right)
1110+
/// ));
1111+
/// # }
1112+
/// ```
1113+
#[must_use]
1114+
pub fn symmetric_difference_with_key<F>(mut self, other: Self, mut f: F) -> Self
10401115
where
10411116
F: FnMut(&K, V, V) -> Option<V>,
10421117
{
@@ -1056,6 +1131,32 @@ where
10561131
out.union(self)
10571132
}
10581133

1134+
/// Construct the relative complement between two maps by discarding keys
1135+
/// which occur in `other`.
1136+
///
1137+
/// Time: O(m log n) where m is the size of the other map
1138+
///
1139+
/// # Examples
1140+
///
1141+
/// ```
1142+
/// # #[macro_use] extern crate im;
1143+
/// # use im::ordmap::OrdMap;
1144+
/// # fn main() {
1145+
/// let map1 = ordmap!{1 => 1, 3 => 4};
1146+
/// let map2 = ordmap!{2 => 2, 3 => 5};
1147+
/// let expected = ordmap!{1 => 1};
1148+
/// assert_eq!(expected, map1.relative_complement(map2));
1149+
/// # }
1150+
/// ```
1151+
#[inline]
1152+
#[must_use]
1153+
pub fn relative_complement(mut self, other: Self) -> Self {
1154+
for (key, _) in other {
1155+
let _ = self.remove(&key);
1156+
}
1157+
self
1158+
}
1159+
10591160
/// Construct the intersection of two maps, keeping the values
10601161
/// from the current map.
10611162
///

src/hash/set.rs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,10 @@ where
487487
i.into_iter().fold(Self::default(), Self::union)
488488
}
489489

490-
/// Construct the difference between two sets.
490+
/// Construct the symmetric difference between two sets.
491+
///
492+
/// This is an alias for the
493+
/// [`symmetric_difference`][symmetric_difference] method.
491494
///
492495
/// Time: O(n log n)
493496
///
@@ -504,7 +507,28 @@ where
504507
/// # }
505508
/// ```
506509
#[must_use]
507-
pub fn difference(mut self, other: Self) -> Self {
510+
pub fn difference(self, other: Self) -> Self {
511+
self.symmetric_difference(other)
512+
}
513+
514+
/// Construct the symmetric difference between two sets.
515+
///
516+
/// Time: O(n log n)
517+
///
518+
/// # Examples
519+
///
520+
/// ```
521+
/// # #[macro_use] extern crate im;
522+
/// # use im::hashset::HashSet;
523+
/// # fn main() {
524+
/// let set1 = hashset!{1, 2};
525+
/// let set2 = hashset!{2, 3};
526+
/// let expected = hashset!{1, 3};
527+
/// assert_eq!(expected, set1.symmetric_difference(set2));
528+
/// # }
529+
/// ```
530+
#[must_use]
531+
pub fn symmetric_difference(mut self, other: Self) -> Self {
508532
for value in other {
509533
if self.remove(&value).is_none() {
510534
self.insert(value);
@@ -513,6 +537,31 @@ where
513537
self
514538
}
515539

540+
/// Construct the relative complement between two sets, that is the set
541+
/// of values in `self` that do not occur in `other`.
542+
///
543+
/// Time: O(m log n) where m is the size of the other set
544+
///
545+
/// # Examples
546+
///
547+
/// ```
548+
/// # #[macro_use] extern crate im;
549+
/// # use im::ordset::OrdSet;
550+
/// # fn main() {
551+
/// let set1 = ordset!{1, 2};
552+
/// let set2 = ordset!{2, 3};
553+
/// let expected = ordset!{1};
554+
/// assert_eq!(expected, set1.relative_complement(set2));
555+
/// # }
556+
/// ```
557+
#[must_use]
558+
pub fn relative_complement(mut self, other: Self) -> Self {
559+
for value in other {
560+
let _ = self.remove(&value);
561+
}
562+
self
563+
}
564+
516565
/// Construct the intersection of two sets.
517566
///
518567
/// Time: O(n log n)

src/ord/map.rs

Lines changed: 108 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -942,9 +942,12 @@ where
942942
.fold(Self::default(), |a, b| a.union_with_key(b, &f))
943943
}
944944

945-
/// Construct the difference between two maps by discarding keys
945+
/// Construct the symmetric difference between two maps by discarding keys
946946
/// which occur in both maps.
947947
///
948+
/// This is an alias for the
949+
/// [`symmetric_difference`][symmetric_difference] method.
950+
///
948951
/// Time: O(n log n)
949952
///
950953
/// # Examples
@@ -962,26 +965,69 @@ where
962965
#[inline]
963966
#[must_use]
964967
pub fn difference(self, other: Self) -> Self {
965-
self.difference_with_key(other, |_, _, _| None)
968+
self.symmetric_difference(other)
969+
}
970+
971+
/// Construct the symmetric difference between two maps by discarding keys
972+
/// which occur in both maps.
973+
///
974+
/// Time: O(n log n)
975+
///
976+
/// # Examples
977+
///
978+
/// ```
979+
/// # #[macro_use] extern crate im;
980+
/// # use im::ordmap::OrdMap;
981+
/// # fn main() {
982+
/// let map1 = ordmap!{1 => 1, 3 => 4};
983+
/// let map2 = ordmap!{2 => 2, 3 => 5};
984+
/// let expected = ordmap!{1 => 1, 2 => 2};
985+
/// assert_eq!(expected, map1.symmetric_difference(map2));
986+
/// # }
987+
/// ```
988+
#[inline]
989+
#[must_use]
990+
pub fn symmetric_difference(self, other: Self) -> Self {
991+
self.symmetric_difference_with_key(other, |_, _, _| None)
966992
}
967993

968-
/// Construct the difference between two maps by using a function
994+
/// Construct the symmetric difference between two maps by using a function
969995
/// to decide what to do if a key occurs in both.
970996
///
997+
/// This is an alias for the
998+
/// [`symmetric_difference_with`][symmetric_difference_with] method.
999+
///
9711000
/// Time: O(n log n)
9721001
#[inline]
9731002
#[must_use]
974-
pub fn difference_with<F>(self, other: Self, mut f: F) -> Self
1003+
pub fn difference_with<F>(self, other: Self, f: F) -> Self
9751004
where
9761005
F: FnMut(V, V) -> Option<V>,
9771006
{
978-
self.difference_with_key(other, |_, a, b| f(a, b))
1007+
self.symmetric_difference_with(other, f)
9791008
}
9801009

981-
/// Construct the difference between two maps by using a function
1010+
/// Construct the symmetric difference between two maps by using a function
1011+
/// to decide what to do if a key occurs in both.
1012+
///
1013+
/// Time: O(n log n)
1014+
#[inline]
1015+
#[must_use]
1016+
pub fn symmetric_difference_with<F>(self, other: Self, mut f: F) -> Self
1017+
where
1018+
F: FnMut(V, V) -> Option<V>,
1019+
{
1020+
self.symmetric_difference_with_key(other, |_, a, b| f(a, b))
1021+
}
1022+
1023+
/// Construct the symmetric difference between two maps by using a function
9821024
/// to decide what to do if a key occurs in both. The function
9831025
/// receives the key as well as both values.
9841026
///
1027+
/// This is an alias for the
1028+
/// [`symmetric_difference_with_key`][symmetric_difference_with_key]
1029+
/// method.
1030+
///
9851031
/// Time: O(n log n)
9861032
///
9871033
/// # Examples
@@ -1000,7 +1046,36 @@ where
10001046
/// # }
10011047
/// ```
10021048
#[must_use]
1003-
pub fn difference_with_key<F>(mut self, other: Self, mut f: F) -> Self
1049+
pub fn difference_with_key<F>(self, other: Self, f: F) -> Self
1050+
where
1051+
F: FnMut(&K, V, V) -> Option<V>,
1052+
{
1053+
self.symmetric_difference_with_key(other, f)
1054+
}
1055+
1056+
/// Construct the symmetric difference between two maps by using a function
1057+
/// to decide what to do if a key occurs in both. The function
1058+
/// receives the key as well as both values.
1059+
///
1060+
/// Time: O(n log n)
1061+
///
1062+
/// # Examples
1063+
///
1064+
/// ```
1065+
/// # #[macro_use] extern crate im;
1066+
/// # use im::ordmap::OrdMap;
1067+
/// # fn main() {
1068+
/// let map1 = ordmap!{1 => 1, 3 => 4};
1069+
/// let map2 = ordmap!{2 => 2, 3 => 5};
1070+
/// let expected = ordmap!{1 => 1, 2 => 2, 3 => 9};
1071+
/// assert_eq!(expected, map1.symmetric_difference_with_key(
1072+
/// map2,
1073+
/// |key, left, right| Some(left + right)
1074+
/// ));
1075+
/// # }
1076+
/// ```
1077+
#[must_use]
1078+
pub fn symmetric_difference_with_key<F>(mut self, other: Self, mut f: F) -> Self
10041079
where
10051080
F: FnMut(&K, V, V) -> Option<V>,
10061081
{
@@ -1020,6 +1095,32 @@ where
10201095
out.union(self)
10211096
}
10221097

1098+
/// Construct the relative complement between two maps by discarding keys
1099+
/// which occur in `other`.
1100+
///
1101+
/// Time: O(m log n) where m is the size of the other map
1102+
///
1103+
/// # Examples
1104+
///
1105+
/// ```
1106+
/// # #[macro_use] extern crate im;
1107+
/// # use im::ordmap::OrdMap;
1108+
/// # fn main() {
1109+
/// let map1 = ordmap!{1 => 1, 3 => 4};
1110+
/// let map2 = ordmap!{2 => 2, 3 => 5};
1111+
/// let expected = ordmap!{1 => 1};
1112+
/// assert_eq!(expected, map1.relative_complement(map2));
1113+
/// # }
1114+
/// ```
1115+
#[inline]
1116+
#[must_use]
1117+
pub fn relative_complement(mut self, other: Self) -> Self {
1118+
for (key, _) in other {
1119+
let _ = self.remove(&key);
1120+
}
1121+
self
1122+
}
1123+
10231124
/// Construct the intersection of two maps, keeping the values
10241125
/// from the current map.
10251126
///

0 commit comments

Comments
 (0)