sort_by_borrowed_key/lib.rs
1/// A crate to add two more sorting methods
2/// ---
3///
4/// Say you have a vector of tuples, which you would like to sort by one of the
5/// elements (maybe you got it by using the enumerate or zip iterator methods,
6/// then collected into a Vec). Now, if you write the following, you will get
7/// lifetime errors:
8/// ```compile_fail
9/// let mut letters = vec![
10/// (1, "C".to_string()),
11/// (2, "B".to_string()),
12/// (3, "B".to_string()),
13/// (4, "A".to_string())
14/// ];
15/// letters.sort_by_key(|x| &x.1);
16/// println!("Letters: {:?}", letters);
17/// ```
18/// So you might try not borrowing, but then you realize String isn't Copy:
19/// ```compile_fail
20/// let mut letters = vec![
21/// (1, "C".to_string()),
22/// (2, "B".to_string()),
23/// (3, "B".to_string()),
24/// (4, "A".to_string())
25/// ];
26/// letters.sort_by_key(|x| x.1);
27/// println!("Letters: {:?}", letters);
28/// ```
29/// So this fails because you'd be moving out of the array! You don't want to
30/// have to expensively clone all of these strings just to compare them. That's
31/// where this library comes in:
32/// ```
33/// use sort_by_borrowed_key::SortByBorrowedKey;
34/// let mut letters = vec![
35/// (1, "C".to_string()),
36/// (2, "B".to_string()),
37/// (3, "B".to_string()),
38/// (4, "A".to_string())
39/// ];
40/// letters.sort_by_borrowed_key(|x| &x.1);
41/// let expected = vec![
42/// (4, "A".to_string()),
43/// (2, "B".to_string()),
44/// (3, "B".to_string()),
45/// (1, "C".to_string())
46/// ];
47/// assert_eq!(letters, expected);
48/// ```
49/// That's it! The only other thing this crate adds is a unstable-sort version
50/// of the same method, `sort_unstable_by_borrowed_key`, which is faster but may
51/// change of the order of equal elements (see the docs for
52/// `[T]::sort_unstable`).
53///
54pub trait SortByBorrowedKey<T> {
55 fn sort_by_borrowed_key<K, F>(&mut self, f: F) where
56 F: for<'a> Fn(&'a T) -> &'a K,
57 K: Ord;
58 fn sort_unstable_by_borrowed_key<K, F>(&mut self, f: F) where
59 F: for<'a> Fn(&'a T) -> &'a K,
60 K: Ord;
61}
62
63impl<T> SortByBorrowedKey<T> for [T] {
64 fn sort_by_borrowed_key<K, F>(&mut self, f: F) where
65 F: for<'a> Fn(&'a T) -> &'a K,
66 K: Ord {
67 self.sort_by(|a, b| {
68 f(a).cmp(f(b))
69 });
70 }
71 fn sort_unstable_by_borrowed_key<K, F>(&mut self, f: F) where
72 F: for<'a> Fn(&'a T) -> &'a K,
73 K: Ord {
74 self.sort_unstable_by(|a, b| {
75 f(a).cmp(f(b))
76 });
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use crate::*;
83 #[test]
84 fn test_stable() {
85 let mut letters = vec![
86 (1, "C".to_string()),
87 (2, "B".to_string()),
88 (3, "B".to_string()),
89 (4, "A".to_string())
90 ];
91 letters.sort_by_borrowed_key(|x| &x.1);
92 let expected = vec![
93 (4, "A".to_string()),
94 (2, "B".to_string()),
95 (3, "B".to_string()),
96 (1, "C".to_string())
97 ];
98 assert_eq!(letters, expected);
99 }
100}