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