From 034ef079ef401d66cab806e967a8390bfb05cb6a Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Sun, 27 Jul 2014 17:04:44 +0200 Subject: [PATCH 1/4] doc: TreeSet methods and main example. --- src/libcollections/treemap.rs | 199 +++++++++++++++++++++++++++++++--- 1 file changed, 183 insertions(+), 16 deletions(-) diff --git a/src/libcollections/treemap.rs b/src/libcollections/treemap.rs index 9bc0a1abbc5f..442a4ded733c 100644 --- a/src/libcollections/treemap.rs +++ b/src/libcollections/treemap.rs @@ -138,7 +138,7 @@ impl Default for TreeMap { } impl TreeMap { - /// Create an empty TreeMap + /// Create an empty `TreeMap`. pub fn new() -> TreeMap { TreeMap{root: None, length: 0} } /// Get a lazy iterator over the keys in the map. @@ -232,6 +232,7 @@ impl TreeMap { /// Return the value for which `f(key)` returns `Equal`. `f` is invoked /// with current key and guides tree navigation. That means `f` should /// be aware of natural ordering of the tree. + /// /// # Example /// /// ``` @@ -633,15 +634,68 @@ impl<'a, T> Iterator<&'a T> for RevSetItems<'a, T> { /// ```{rust} /// use std::collections::TreeSet; /// -/// let mut tree_set = TreeSet::new(); +/// let mut set = TreeSet::new(); /// -/// tree_set.insert(2i); -/// tree_set.insert(1i); -/// tree_set.insert(3i); +/// set.insert(2i); +/// set.insert(1i); +/// set.insert(3i); /// -/// for i in tree_set.iter() { +/// for i in set.iter() { /// println!("{}", i) // prints 1, then 2, then 3 /// } +/// +/// set.remove(&3); +/// +/// if !set.contains(&3) { +/// println!("set does not contain a 3 anymore"); +/// } +/// ``` +/// +/// The easiest way to use `TreeSet` with a custom type is to implement `Ord`. +/// We must also implement `PartialEq`, `Eq` and `PartialOrd`. +/// +/// ``` +/// use std::collections::TreeSet; +/// +/// // We need `Eq` and `PartialEq`, these can be derived. +/// #[deriving(Eq, PartialEq)] +/// struct Troll<'a> { +/// name: &'a str, +/// level: uint, +/// } +/// +/// // Implement `Ord` and sort trolls by level. +/// impl<'a> Ord for Troll<'a> { +/// fn cmp(&self, other: &Troll) -> Ordering { +/// // If we swap `self` and `other`, we get descended ordering. +/// self.level.cmp(&other.level) +/// } +/// } +/// +/// // `PartialOrd` needs to be implemented as well. +/// impl<'a> PartialOrd for Troll<'a> { +/// fn partial_cmp(&self, other: &Troll) -> Option { +/// Some(self.cmp(other)) +/// } +/// } +/// +/// let mut trolls = TreeSet::new(); +/// +/// trolls.insert(Troll { name: "Orgarr", level: 2 }); +/// trolls.insert(Troll { name: "Blargarr", level: 3 }); +/// trolls.insert(Troll { name: "Kron the Smelly One", level: 4 }); +/// trolls.insert(Troll { name: "Wartilda", level: 1 }); +/// +/// println!("You are facing {} trolls!", trolls.len()); +/// +/// // Print the trolls, ordered by level with smallest level first +/// for x in trolls.iter() { +/// println!("level {}: {}!", x.level, x.name); +/// } +/// +/// // Kill all trolls +/// trolls.clear(); +/// assert_eq!(trolls.len(), 0); /// ``` #[deriving(Clone)] pub struct TreeSet { @@ -732,25 +786,66 @@ impl Default for TreeSet { } impl TreeSet { - /// Create an empty TreeSet + /// Create an empty `TreeSet`. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeSet; + /// let mut set: TreeSet = TreeSet::new(); + /// ``` #[inline] pub fn new() -> TreeSet { TreeSet{map: TreeMap::new()} } - /// Get a lazy iterator over the values in the set. - /// Requires that it be frozen (immutable). + /// Get a lazy iterator over the values in the set, in ascending order. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeSet; + /// let set: TreeSet = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect(); + /// + /// // Will print in ascending order. + /// for x in set.iter() { + /// println!("{}", x); + /// } + /// ``` #[inline] pub fn iter<'a>(&'a self) -> SetItems<'a, T> { SetItems{iter: self.map.iter()} } - /// Get a lazy iterator over the values in the set. - /// Requires that it be frozen (immutable). + /// Get a lazy iterator over the values in the set, in descending order. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeSet; + /// let set: TreeSet = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect(); + /// + /// // Will print in descending order. + /// for x in set.rev_iter() { + /// println!("{}", x); + /// } + /// ``` #[inline] pub fn rev_iter<'a>(&'a self) -> RevSetItems<'a, T> { RevSetItems{iter: self.map.rev_iter()} } - /// Get a lazy iterator that consumes the set. + /// Creates a consuming iterator, that is, one that moves each value out of the + /// set in ascending order. The set cannot be used after calling this. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeSet; + /// let set: TreeSet = [1i, 4, 3, 5, 2].iter().map(|&x| x).collect(); + /// + /// // Not possible with a regular `.iter()` + /// let v: Vec = set.move_iter().collect(); + /// assert_eq!(v, vec![1, 2, 3, 4, 5]); + /// ``` #[inline] pub fn move_iter(self) -> MoveSetItems { self.map.move_iter().map(|(value, _)| value) @@ -770,24 +865,96 @@ impl TreeSet { SetItems{iter: self.map.upper_bound(v)} } - /// Visit the values (in-order) representing the difference + /// Visit the values representing the difference, in ascending order. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeSet; + /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); + /// + /// // Can be seen as `a - b`. + /// for x in a.difference(&b) { + /// println!("{}", x); // Print 1 then 2 + /// } + /// + /// let diff: TreeSet = a.difference(&b).map(|&x| x).collect(); + /// assert_eq!(diff, [1, 2].iter().map(|&x| x).collect()); + /// + /// // Note that difference is not symmetric, + /// // and `b - a` means something else: + /// let diff: TreeSet = b.difference(&a).map(|&x| x).collect(); + /// assert_eq!(diff, [4, 5].iter().map(|&x| x).collect()); + /// ``` pub fn difference<'a>(&'a self, other: &'a TreeSet) -> DifferenceItems<'a, T> { DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} } - /// Visit the values (in-order) representing the symmetric difference + /// Visit the values representing the symmetric difference, in ascending order. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeSet; + /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); + /// + /// // Print 1, 2, 4, 5 in ascending order. + /// for x in a.symmetric_difference(&b) { + /// println!("{}", x); + /// } + /// + /// let diff1: TreeSet = a.symmetric_difference(&b).map(|&x| x).collect(); + /// let diff2: TreeSet = b.symmetric_difference(&a).map(|&x| x).collect(); + /// + /// assert_eq!(diff1, diff2); + /// assert_eq!(diff1, [1, 2, 4, 5].iter().map(|&x| x).collect()); + /// ``` pub fn symmetric_difference<'a>(&'a self, other: &'a TreeSet) -> SymDifferenceItems<'a, T> { SymDifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} } - /// Visit the values (in-order) representing the intersection + /// Visit the values representing the intersection, in ascending order. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeSet; + /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: TreeSet = [2, 3, 4].iter().map(|&x| x).collect(); + /// + /// // Print 2, 3 in ascending order. + /// for x in a.intersection(&b) { + /// println!("{}", x); + /// } + /// + /// let diff: TreeSet = a.intersection(&b).map(|&x| x).collect(); + /// assert_eq!(diff, [2, 3].iter().map(|&x| x).collect()); + /// ``` pub fn intersection<'a>(&'a self, other: &'a TreeSet) -> IntersectionItems<'a, T> { IntersectionItems{a: self.iter().peekable(), b: other.iter().peekable()} } - /// Visit the values (in-order) representing the union + /// Visit the values representing the union, in ascending order. + /// + /// # Example + /// + /// ``` + /// use std::collections::HashSet; + /// let a: HashSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: HashSet = [3, 4, 5].iter().map(|&x| x).collect(); + /// + /// // Print 1, 2, 3, 4, 5 in ascending order. + /// for x in a.union(&b) { + /// println!("{}", x); + /// } + /// + /// let diff: HashSet = a.union(&b).map(|&x| x).collect(); + /// assert_eq!(diff, [1, 2, 3, 4, 5].iter().map(|&x| x).collect()); + /// ``` pub fn union<'a>(&'a self, other: &'a TreeSet) -> UnionItems<'a, T> { UnionItems{a: self.iter().peekable(), b: other.iter().peekable()} } From 8c34a97b37a2f546490546c5cac97c9add8a2972 Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Sun, 27 Jul 2014 17:44:07 +0200 Subject: [PATCH 2/4] doc: TreeMap methods with examples. Small corrections for TreeSet examples. --- src/libcollections/treemap.rs | 265 +++++++++++++++++++++++++++++++--- 1 file changed, 248 insertions(+), 17 deletions(-) diff --git a/src/libcollections/treemap.rs b/src/libcollections/treemap.rs index 442a4ded733c..ec13c0a28889 100644 --- a/src/libcollections/treemap.rs +++ b/src/libcollections/treemap.rs @@ -43,10 +43,10 @@ use std::hash::{Writer, Hash}; use {Collection, Mutable, Set, MutableSet, MutableMap, Map, MutableSeq}; use vec::Vec; -// This is implemented as an AA tree, which is a simplified variation of -// a red-black tree where red (horizontal) nodes can only be added -// as a right child. The time complexity is the same, and re-balancing -// operations are more frequent but also cheaper. +/// This is implemented as an AA tree, which is a simplified variation of +/// a red-black tree where red (horizontal) nodes can only be added +/// as a right child. The time complexity is the same, and re-balancing +/// operations are more frequent but also cheaper. // Future improvements: @@ -59,7 +59,6 @@ use vec::Vec; // * union: | // These would be convenient since the methods work like `each` -#[allow(missing_doc)] #[deriving(Clone)] pub struct TreeMap { root: Option>>, @@ -139,20 +138,73 @@ impl Default for TreeMap { impl TreeMap { /// Create an empty `TreeMap`. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// let mut map: TreeMap<&str, int> = TreeMap::new(); + /// ``` pub fn new() -> TreeMap { TreeMap{root: None, length: 0} } - /// Get a lazy iterator over the keys in the map. + /// Get a lazy iterator over the keys in the map, in ascending order. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// let mut map = TreeMap::new(); + /// map.insert("a", 1i); + /// map.insert("c", 3i); + /// map.insert("b", 2i); + /// + /// // Print "a", "b", "c" in order. + /// for x in map.keys() { + /// println!("{}", x); + /// } + /// ``` pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { self.iter().map(|(k, _v)| k) } - /// Get a lazy iterator over the values in the map. + /// Get a lazy iterator over the values in the map, in ascending order + /// with respect to the corresponding keys. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// let mut map = TreeMap::new(); + /// map.insert("a", 1i); + /// map.insert("c", 3i); + /// map.insert("b", 2i); + /// + /// // Print 1, 2, 3 ordered by keys. + /// for x in map.values() { + /// println!("{}", x); + /// } + /// ``` pub fn values<'a>(&'a self) -> Values<'a, K, V> { self.iter().map(|(_k, v)| v) } - /// Get a lazy iterator over the key-value pairs in the map. + /// Get a lazy iterator over the key-value pairs in the map, in ascending order. /// Requires that it be frozen (immutable). + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// let mut map = TreeMap::new(); + /// map.insert("a", 1i); + /// map.insert("c", 3i); + /// map.insert("b", 2i); + /// + /// // Print contents in ascending order + /// for (key, value) in map.iter() { + /// println!("{}: {}", key, value); + /// } + /// ``` pub fn iter<'a>(&'a self) -> Entries<'a, K, V> { Entries { stack: vec!(), @@ -162,14 +214,49 @@ impl TreeMap { } } - /// Get a lazy reverse iterator over the key-value pairs in the map. + /// Get a lazy reverse iterator over the key-value pairs in the map, in descending order. /// Requires that it be frozen (immutable). + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// let mut map = TreeMap::new(); + /// map.insert("a", 1i); + /// map.insert("c", 3i); + /// map.insert("b", 2i); + /// + /// // Print contents in descending order + /// for (key, value) in map.rev_iter() { + /// println!("{}: {}", key, value); + /// } + /// ``` pub fn rev_iter<'a>(&'a self) -> RevEntries<'a, K, V> { RevEntries{iter: self.iter()} } /// Get a lazy forward iterator over the key-value pairs in the /// map, with the values being mutable. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// let mut map = TreeMap::new(); + /// map.insert("a", 1i); + /// map.insert("c", 3i); + /// map.insert("b", 2i); + /// + /// // Add 10 until we find "b" + /// for (key, value) in map.mut_iter() { + /// *value += 10; + /// if key == &"b" { break } + /// } + /// + /// assert_eq!(map.find(&"a"), Some(&11)); + /// assert_eq!(map.find(&"b"), Some(&12)); + /// assert_eq!(map.find(&"c"), Some(&3)); + /// ``` pub fn mut_iter<'a>(&'a mut self) -> MutEntries<'a, K, V> { MutEntries { stack: vec!(), @@ -180,12 +267,47 @@ impl TreeMap { } /// Get a lazy reverse iterator over the key-value pairs in the /// map, with the values being mutable. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// let mut map = TreeMap::new(); + /// map.insert("a", 1i); + /// map.insert("c", 3i); + /// map.insert("b", 2i); + /// + /// // Add 10 until we find "b" + /// for (key, value) in map.mut_rev_iter() { + /// *value += 10; + /// if key == &"b" { break } + /// } + /// + /// assert_eq!(map.find(&"a"), Some(&1)); + /// assert_eq!(map.find(&"b"), Some(&12)); + /// assert_eq!(map.find(&"c"), Some(&13)); + /// ``` pub fn mut_rev_iter<'a>(&'a mut self) -> RevMutEntries<'a, K, V> { RevMutEntries{iter: self.mut_iter()} } - /// Get a lazy iterator that consumes the treemap. + /// Get a lazy iterator that consumes the treemap, it is not usable + /// after calling this. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// let mut map = TreeMap::new(); + /// map.insert("a", 1i); + /// map.insert("c", 3i); + /// map.insert("b", 2i); + /// + /// // Not possible with a regular `.iter()` + /// let vec: Vec<(&str, int)> = map.move_iter().collect(); + /// assert_eq!(vec, vec![("a", 1), ("b", 2), ("c", 3)]); + /// ``` pub fn move_iter(self) -> MoveEntries { let TreeMap { root: root, length: length } = self; let stk = match root { @@ -302,12 +424,44 @@ impl TreeMap { /// Return a lazy iterator to the first key-value pair whose key is not less than `k` /// If all keys in map are less than `k` an empty iterator is returned. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// + /// let mut map = TreeMap::new(); + /// map.insert(2i, "a"); + /// map.insert(4, "b"); + /// map.insert(6, "c"); + /// map.insert(8, "d"); + /// + /// assert_eq!(map.lower_bound(&4).next(), Some((&4, &"b"))); + /// assert_eq!(map.lower_bound(&5).next(), Some((&6, &"c"))); + /// assert_eq!(map.lower_bound(&10).next(), None); + /// ``` pub fn lower_bound<'a>(&'a self, k: &K) -> Entries<'a, K, V> { bound_setup!(self.iter_for_traversal(), k, true) } /// Return a lazy iterator to the first key-value pair whose key is greater than `k` - /// If all keys in map are not greater than `k` an empty iterator is returned. + /// If all keys in map are less than or equal to `k` an empty iterator is returned. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// + /// let mut map = TreeMap::new(); + /// map.insert(2i, "a"); + /// map.insert(4, "b"); + /// map.insert(6, "c"); + /// map.insert(8, "d"); + /// + /// assert_eq!(map.upper_bound(&4).next(), Some((&6, &"c"))); + /// assert_eq!(map.upper_bound(&5).next(), Some((&6, &"c"))); + /// assert_eq!(map.upper_bound(&10).next(), None); + /// ``` pub fn upper_bound<'a>(&'a self, k: &K) -> Entries<'a, K, V> { bound_setup!(self.iter_for_traversal(), k, false) } @@ -328,6 +482,31 @@ impl TreeMap { /// /// If all keys in map are less than `k` an empty iterator is /// returned. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// + /// let mut map = TreeMap::new(); + /// map.insert(2i, "a"); + /// map.insert(4, "b"); + /// map.insert(6, "c"); + /// map.insert(8, "d"); + /// + /// assert_eq!(map.mut_lower_bound(&4).next(), Some((&4, &mut "b"))); + /// assert_eq!(map.mut_lower_bound(&5).next(), Some((&6, &mut "c"))); + /// assert_eq!(map.mut_lower_bound(&10).next(), None); + /// + /// for (key, value) in map.mut_lower_bound(&4) { + /// *value = "changed"; + /// } + /// + /// assert_eq!(map.find(&2), Some(&"a")); + /// assert_eq!(map.find(&4), Some(&"changed")); + /// assert_eq!(map.find(&6), Some(&"changed")); + /// assert_eq!(map.find(&8), Some(&"changed")); + /// ``` pub fn mut_lower_bound<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> { bound_setup!(self.mut_iter_for_traversal(), k, true) } @@ -335,8 +514,33 @@ impl TreeMap { /// Return a lazy iterator to the first key-value pair (with the /// value being mutable) whose key is greater than `k`. /// - /// If all keys in map are not greater than `k` an empty iterator + /// If all keys in map are less than or equal to `k` an empty iterator /// is returned. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeMap; + /// + /// let mut map = TreeMap::new(); + /// map.insert(2i, "a"); + /// map.insert(4, "b"); + /// map.insert(6, "c"); + /// map.insert(8, "d"); + /// + /// assert_eq!(map.mut_upper_bound(&4).next(), Some((&6, &mut "c"))); + /// assert_eq!(map.mut_upper_bound(&5).next(), Some((&6, &mut "c"))); + /// assert_eq!(map.mut_upper_bound(&10).next(), None); + /// + /// for (key, value) in map.mut_upper_bound(&4) { + /// *value = "changed"; + /// } + /// + /// assert_eq!(map.find(&2), Some(&"a")); + /// assert_eq!(map.find(&4), Some(&"b")); + /// assert_eq!(map.find(&6), Some(&"changed")); + /// assert_eq!(map.find(&8), Some(&"changed")); + /// ``` pub fn mut_upper_bound<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> { bound_setup!(self.mut_iter_for_traversal(), k, false) } @@ -853,13 +1057,36 @@ impl TreeSet { /// Get a lazy iterator pointing to the first value not less than `v` (greater or equal). /// If all elements in the set are less than `v` empty iterator is returned. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeSet; + /// let set: TreeSet = [2, 4, 6, 8].iter().map(|&x| x).collect(); + /// + /// assert_eq!(set.lower_bound(&4).next(), Some(&4)); + /// assert_eq!(set.lower_bound(&5).next(), Some(&6)); + /// assert_eq!(set.lower_bound(&10).next(), None); + /// ``` #[inline] pub fn lower_bound<'a>(&'a self, v: &T) -> SetItems<'a, T> { SetItems{iter: self.map.lower_bound(v)} } /// Get a lazy iterator pointing to the first value greater than `v`. - /// If all elements in the set are not greater than `v` empty iterator is returned. + /// If all elements in the set are less than or equal to `v` an + /// empty iterator is returned. + /// + /// # Example + /// + /// ``` + /// use std::collections::TreeSet; + /// let set: TreeSet = [2, 4, 6, 8].iter().map(|&x| x).collect(); + /// + /// assert_eq!(set.upper_bound(&4).next(), Some(&6)); + /// assert_eq!(set.upper_bound(&5).next(), Some(&6)); + /// assert_eq!(set.upper_bound(&10).next(), None); + /// ``` #[inline] pub fn upper_bound<'a>(&'a self, v: &T) -> SetItems<'a, T> { SetItems{iter: self.map.upper_bound(v)} @@ -871,6 +1098,7 @@ impl TreeSet { /// /// ``` /// use std::collections::TreeSet; + /// /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); /// @@ -897,6 +1125,7 @@ impl TreeSet { /// /// ``` /// use std::collections::TreeSet; + /// /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); /// @@ -922,6 +1151,7 @@ impl TreeSet { /// /// ``` /// use std::collections::TreeSet; + /// /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); /// let b: TreeSet = [2, 3, 4].iter().map(|&x| x).collect(); /// @@ -943,16 +1173,17 @@ impl TreeSet { /// # Example /// /// ``` - /// use std::collections::HashSet; - /// let a: HashSet = [1, 2, 3].iter().map(|&x| x).collect(); - /// let b: HashSet = [3, 4, 5].iter().map(|&x| x).collect(); + /// use std::collections::TreeSet; + /// + /// let a: TreeSet = [1, 2, 3].iter().map(|&x| x).collect(); + /// let b: TreeSet = [3, 4, 5].iter().map(|&x| x).collect(); /// /// // Print 1, 2, 3, 4, 5 in ascending order. /// for x in a.union(&b) { /// println!("{}", x); /// } /// - /// let diff: HashSet = a.union(&b).map(|&x| x).collect(); + /// let diff: TreeSet = a.union(&b).map(|&x| x).collect(); /// assert_eq!(diff, [1, 2, 3, 4, 5].iter().map(|&x| x).collect()); /// ``` pub fn union<'a>(&'a self, other: &'a TreeSet) -> UnionItems<'a, T> { From 53c639184cbbdb95d316cb36691a2f9722dfc41a Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Sun, 27 Jul 2014 18:19:04 +0200 Subject: [PATCH 3/4] doc: Main example for TreeMap. --- src/libcollections/treemap.rs | 101 ++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/src/libcollections/treemap.rs b/src/libcollections/treemap.rs index ec13c0a28889..5a39a34671aa 100644 --- a/src/libcollections/treemap.rs +++ b/src/libcollections/treemap.rs @@ -47,6 +47,107 @@ use vec::Vec; /// a red-black tree where red (horizontal) nodes can only be added /// as a right child. The time complexity is the same, and re-balancing /// operations are more frequent but also cheaper. +/// +/// # Example +/// +/// ``` +/// use std::collections::TreeMap; +/// +/// let mut map = TreeMap::new(); +/// +/// map.insert(2i, "bar"); +/// map.insert(1i, "foo"); +/// map.insert(3i, "quux"); +/// +/// // In ascending order by keys +/// for (key, value) in map.iter() { +/// println!("{}: {}", key, value); +/// } +/// +/// // Print 1, 2, 3 +/// for key in map.keys() { +/// println!("{}", key); +/// } +/// +/// // Print `foo`, `bar`, `quux` +/// for key in map.values() { +/// println!("{}", key); +/// } +/// +/// map.remove(&1); +/// assert_eq!(map.len(), 2); +/// +/// if !map.contains_key(&1) { +/// println!("1 is no more"); +/// } +/// +/// for key in range(0, 4) { +/// match map.find(&key) { +/// Some(val) => println!("{} has a value: {}", key, val), +/// None => println!("{} not in map", key), +/// } +/// } +/// +/// map.clear(); +/// assert!(map.is_empty()); +/// ``` +/// +/// The easiest way to use `TreeMap` with a custom type as keys is to implement `Ord`. +/// We must also implement `PartialEq`, `Eq` and `PartialOrd`. +/// +/// ``` +/// use std::collections::TreeMap; +/// +/// // We need `Eq` and `PartialEq`, these can be derived. +/// #[deriving(Eq, PartialEq)] +/// struct Troll<'a> { +/// name: &'a str, +/// level: uint, +/// } +/// +/// // Implement `Ord` and sort trolls by level. +/// impl<'a> Ord for Troll<'a> { +/// fn cmp(&self, other: &Troll) -> Ordering { +/// // If we swap `self` and `other`, we get descended ordering. +/// self.level.cmp(&other.level) +/// } +/// } +/// +/// // `PartialOrd` needs to be implemented as well. +/// impl<'a> PartialOrd for Troll<'a> { +/// fn partial_cmp(&self, other: &Troll) -> Option { +/// Some(self.cmp(other)) +/// } +/// } +/// +/// // Use a map to store trolls, sorted by level, and track a list of +/// // heroes slain. +/// let mut trolls = TreeMap::new(); +/// +/// trolls.insert(Troll { name: "Orgarr", level: 2 }, +/// vec!["King Karl"]); +/// trolls.insert(Troll { name: "Blargarr", level: 3 }, +/// vec!["Odd"]); +/// trolls.insert(Troll { name: "Kron the Smelly One", level: 4 }, +/// vec!["Omar the Brave", "Peter: Slayer of Trolls"]); +/// trolls.insert(Troll { name: "Wartilda", level: 1 }, +/// vec![]); +/// +/// println!("You are facing {} trolls!", trolls.len()); +/// +/// // Print the trolls, ordered by level with smallest level first +/// for (troll, heroes) in trolls.iter() { +/// let what = if heroes.len() == 1u { "hero" } +/// else { "heroes" }; +/// +/// println!("level {}: '{}' has slain {} {}", +/// troll.level, troll.name, heroes.len(), what); +/// } +/// +/// // Kill all trolls +/// trolls.clear(); +/// assert_eq!(trolls.len(), 0); +/// ``` // Future improvements: From 58d3f109f87eb95998d2b5293a5981c1c5cfa4ce Mon Sep 17 00:00:00 2001 From: Jonas Hietala Date: Sun, 27 Jul 2014 19:57:33 +0200 Subject: [PATCH 4/4] doc: Small rewording. --- src/libcollections/treemap.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/libcollections/treemap.rs b/src/libcollections/treemap.rs index 5a39a34671aa..5de23b42f5c7 100644 --- a/src/libcollections/treemap.rs +++ b/src/libcollections/treemap.rs @@ -64,12 +64,12 @@ use vec::Vec; /// println!("{}: {}", key, value); /// } /// -/// // Print 1, 2, 3 +/// // Prints 1, 2, 3 /// for key in map.keys() { /// println!("{}", key); /// } /// -/// // Print `foo`, `bar`, `quux` +/// // Prints `foo`, `bar`, `quux` /// for key in map.values() { /// println!("{}", key); /// } @@ -108,7 +108,7 @@ use vec::Vec; /// // Implement `Ord` and sort trolls by level. /// impl<'a> Ord for Troll<'a> { /// fn cmp(&self, other: &Troll) -> Ordering { -/// // If we swap `self` and `other`, we get descended ordering. +/// // If we swap `self` and `other`, we get descending ordering. /// self.level.cmp(&other.level) /// } /// } @@ -290,7 +290,6 @@ impl TreeMap { } /// Get a lazy iterator over the key-value pairs in the map, in ascending order. - /// Requires that it be frozen (immutable). /// /// # Example /// @@ -316,7 +315,6 @@ impl TreeMap { } /// Get a lazy reverse iterator over the key-value pairs in the map, in descending order. - /// Requires that it be frozen (immutable). /// /// # Example /// @@ -972,7 +970,7 @@ impl<'a, T> Iterator<&'a T> for RevSetItems<'a, T> { /// // Implement `Ord` and sort trolls by level. /// impl<'a> Ord for Troll<'a> { /// fn cmp(&self, other: &Troll) -> Ordering { -/// // If we swap `self` and `other`, we get descended ordering. +/// // If we swap `self` and `other`, we get descending ordering. /// self.level.cmp(&other.level) /// } /// }