@@ -102,6 +102,26 @@ fn partition_at_index_loop<'a, T, F>(
102102 }
103103}
104104
105+ /// Helper function that returns the index of the minimum element in the slice using the given
106+ /// comparator function
107+ fn min_index < T , F : FnMut ( & T , & T ) -> bool > ( slice : & [ T ] , is_less : & mut F ) -> Option < usize > {
108+ slice
109+ . iter ( )
110+ . enumerate ( )
111+ . reduce ( |acc, t| if is_less ( t. 1 , acc. 1 ) { t } else { acc } )
112+ . map ( |( i, _) | i)
113+ }
114+
115+ /// Helper function that returns the index of the maximum element in the slice using the given
116+ /// comparator function
117+ fn max_index < T , F : FnMut ( & T , & T ) -> bool > ( slice : & [ T ] , is_less : & mut F ) -> Option < usize > {
118+ slice
119+ . iter ( )
120+ . enumerate ( )
121+ . reduce ( |acc, t| if is_less ( acc. 1 , t. 1 ) { t } else { acc } )
122+ . map ( |( i, _) | i)
123+ }
124+
105125/// Reorder the slice such that the element at `index` is at its final sorted position.
106126pub fn partition_at_index < T , F > (
107127 v : & mut [ T ] ,
@@ -120,13 +140,13 @@ where
120140 } else if index == v. len ( ) - 1 {
121141 // Find max element and place it in the last position of the array. We're free to use
122142 // `unwrap()` here because we know v must not be empty.
123- let ( max_index , _ ) = v . iter ( ) . enumerate ( ) . max_by ( from_is_less ( & mut is_less) ) . unwrap ( ) ;
124- v. swap ( max_index , index) ;
143+ let max_idx = max_index ( v , & mut is_less) . unwrap ( ) ;
144+ v. swap ( max_idx , index) ;
125145 } else if index == 0 {
126146 // Find min element and place it in the first position of the array. We're free to use
127147 // `unwrap()` here because we know v must not be empty.
128- let ( min_index , _ ) = v . iter ( ) . enumerate ( ) . min_by ( from_is_less ( & mut is_less) ) . unwrap ( ) ;
129- v. swap ( min_index , index) ;
148+ let min_idx = min_index ( v , & mut is_less) . unwrap ( ) ;
149+ v. swap ( min_idx , index) ;
130150 } else {
131151 partition_at_index_loop ( v, index, & mut is_less, None ) ;
132152 }
@@ -137,16 +157,6 @@ where
137157 ( left, pivot, right)
138158}
139159
140- /// helper function used to find the index of the min/max element
141- /// using e.g. `slice.iter().enumerate().min_by(from_is_less(&mut is_less)).unwrap()`
142- fn from_is_less < T > (
143- is_less : & mut impl FnMut ( & T , & T ) -> bool ,
144- ) -> impl FnMut ( & ( usize , & T ) , & ( usize , & T ) ) -> cmp:: Ordering + ' _ {
145- |& ( _, x) , & ( _, y) | {
146- if is_less ( x, y) { cmp:: Ordering :: Less } else { cmp:: Ordering :: Greater }
147- }
148- }
149-
150160/// Selection algorithm to select the k-th element from the slice in guaranteed O(n) time.
151161/// This is essentially a quickselect that uses Tukey's Ninther for pivot selection
152162fn 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
170180 if k == v. len ( ) - 1 {
171181 // Find max element and place it in the last position of the array. We're free to use
172182 // `unwrap()` here because we know v must not be empty.
173- let ( max_index , _ ) = v . iter ( ) . enumerate ( ) . max_by ( from_is_less ( is_less) ) . unwrap ( ) ;
174- v. swap ( max_index , k) ;
183+ let max_idx = max_index ( v , is_less) . unwrap ( ) ;
184+ v. swap ( max_idx , k) ;
175185 return ;
176186 } else if k == 0 {
177187 // Find min element and place it in the first position of the array. We're free to use
178188 // `unwrap()` here because we know v must not be empty.
179- let ( min_index , _ ) = v . iter ( ) . enumerate ( ) . min_by ( from_is_less ( is_less) ) . unwrap ( ) ;
180- v. swap ( min_index , k) ;
189+ let min_idx = min_index ( v , is_less) . unwrap ( ) ;
190+ v. swap ( min_idx , k) ;
181191 return ;
182192 }
183193
0 commit comments