about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMarkus Everling <markuseverling@gmail.com>2023-05-24 19:33:04 +0000
committerMarkus Everling <markuseverling@gmail.com>2023-05-24 19:33:04 +0000
commitfd5fa012e9bf38b3655d2a076d0f67b058367096 (patch)
treeb3233ae3d6ec2bc2fe0b98be610429269eafa759
parent3d11b655bd7264b2b66c299ac975c5050d40b220 (diff)
downloadrust-fd5fa012e9bf38b3655d2a076d0f67b058367096.tar.gz
rust-fd5fa012e9bf38b3655d2a076d0f67b058367096.zip
Use helper functions for min/max_idx
-rw-r--r--library/core/src/slice/select.rs46
1 files changed, 28 insertions, 18 deletions
diff --git a/library/core/src/slice/select.rs b/library/core/src/slice/select.rs
index ff88cb89a74..ffc193578e0 100644
--- a/library/core/src/slice/select.rs
+++ b/library/core/src/slice/select.rs
@@ -102,6 +102,26 @@ fn partition_at_index_loop<'a, T, F>(
     }
 }
 
+/// Helper function that returns the index of the minimum element in the slice using the given
+/// comparator function
+fn min_index<T, F: FnMut(&T, &T) -> bool>(slice: &[T], is_less: &mut F) -> Option<usize> {
+    slice
+        .iter()
+        .enumerate()
+        .reduce(|acc, t| if is_less(t.1, acc.1) { t } else { acc })
+        .map(|(i, _)| i)
+}
+
+/// Helper function that returns the index of the maximum element in the slice using the given
+/// comparator function
+fn max_index<T, F: FnMut(&T, &T) -> bool>(slice: &[T], is_less: &mut F) -> Option<usize> {
+    slice
+        .iter()
+        .enumerate()
+        .reduce(|acc, t| if is_less(acc.1, t.1) { t } else { acc })
+        .map(|(i, _)| i)
+}
+
 /// Reorder the slice such that the element at `index` is at its final sorted position.
 pub fn partition_at_index<T, F>(
     v: &mut [T],
@@ -120,13 +140,13 @@ where
     } else if index == v.len() - 1 {
         // Find max element and place it in the last position of the array. We're free to use
         // `unwrap()` here because we know v must not be empty.
-        let (max_index, _) = v.iter().enumerate().max_by(from_is_less(&mut is_less)).unwrap();
-        v.swap(max_index, index);
+        let max_idx = max_index(v, &mut is_less).unwrap();
+        v.swap(max_idx, index);
     } else if index == 0 {
         // Find min element and place it in the first position of the array. We're free to use
         // `unwrap()` here because we know v must not be empty.
-        let (min_index, _) = v.iter().enumerate().min_by(from_is_less(&mut is_less)).unwrap();
-        v.swap(min_index, index);
+        let min_idx = min_index(v, &mut is_less).unwrap();
+        v.swap(min_idx, index);
     } else {
         partition_at_index_loop(v, index, &mut is_less, None);
     }
@@ -137,16 +157,6 @@ where
     (left, pivot, right)
 }
 
-/// helper function used to find the index of the min/max element
-/// using e.g. `slice.iter().enumerate().min_by(from_is_less(&mut is_less)).unwrap()`
-fn from_is_less<T>(
-    is_less: &mut impl FnMut(&T, &T) -> bool,
-) -> impl FnMut(&(usize, &T), &(usize, &T)) -> cmp::Ordering + '_ {
-    |&(_, x), &(_, y)| {
-        if is_less(x, y) { cmp::Ordering::Less } else { cmp::Ordering::Greater }
-    }
-}
-
 /// Selection algorithm to select the k-th element from the slice in guaranteed O(n) time.
 /// This is essentially a quickselect that uses Tukey's Ninther for pivot selection
 fn median_of_medians<T, F: FnMut(&T, &T) -> bool>(mut v: &mut [T], is_less: &mut F, mut k: usize) {
@@ -170,14 +180,14 @@ fn median_of_medians<T, F: FnMut(&T, &T) -> bool>(mut v: &mut [T], is_less: &mut
         if k == v.len() - 1 {
             // Find max element and place it in the last position of the array. We're free to use
             // `unwrap()` here because we know v must not be empty.
-            let (max_index, _) = v.iter().enumerate().max_by(from_is_less(is_less)).unwrap();
-            v.swap(max_index, k);
+            let max_idx = max_index(v, is_less).unwrap();
+            v.swap(max_idx, k);
             return;
         } else if k == 0 {
             // Find min element and place it in the first position of the array. We're free to use
             // `unwrap()` here because we know v must not be empty.
-            let (min_index, _) = v.iter().enumerate().min_by(from_is_less(is_less)).unwrap();
-            v.swap(min_index, k);
+            let min_idx = min_index(v, is_less).unwrap();
+            v.swap(min_idx, k);
             return;
         }