Skip to content

Commit 0e87d5d

Browse files
committed
Implement partial_sort_unstable for slice
Signed-off-by: tison <wander4096@gmail.com>
1 parent 7934bbd commit 0e87d5d

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

library/core/src/slice/mod.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3242,6 +3242,77 @@ impl<T> [T] {
32423242
sort::unstable::sort(self, &mut |a, b| f(a).lt(&f(b)));
32433243
}
32443244

3245+
/// Partially sorts the slice in ascending order **without** preserving the initial order
3246+
/// of equal elements.
3247+
#[unstable(feature = "slice_partial_sort_unstable", issue = "149046")]
3248+
#[inline]
3249+
pub fn partial_sort_unstable<R>(&mut self, range: R)
3250+
where
3251+
T: Ord,
3252+
R: RangeBounds<usize>,
3253+
{
3254+
self.partial_sort_unstable_by(range, T::cmp);
3255+
}
3256+
3257+
/// Partially sorts the slice in ascending order with a comparison function, **without**
3258+
/// preserving the initial order of equal elements.
3259+
///
3260+
/// # Examples
3261+
///
3262+
/// ```
3263+
/// #![feature(slice_partial_sort_unstable)]
3264+
///
3265+
/// let mut v = [4, -5, 1, -3, 2];
3266+
/// v.partial_sort_unstable_by(.., |a, b| a.cmp(b));
3267+
/// assert_eq!(v, [-5, -3, 1, 2, 4]);
3268+
///
3269+
/// // reverse sorting
3270+
/// v.partial_sort_unstable_by(.., |a, b| b.cmp(a));
3271+
/// assert_eq!(v, [4, 2, 1, -3, -5]);
3272+
/// ```
3273+
#[unstable(feature = "slice_partial_sort_unstable", issue = "149046")]
3274+
#[inline]
3275+
pub fn partial_sort_unstable_by<F, R>(&mut self, range: R, mut compare: F)
3276+
where
3277+
F: FnMut(&T, &T) -> Ordering,
3278+
R: RangeBounds<usize>,
3279+
{
3280+
let len = self.len();
3281+
let Range { start, end } = slice::range(range, ..len);
3282+
3283+
if start == end {
3284+
// empty range, nothing to do
3285+
return;
3286+
}
3287+
3288+
let index = start;
3289+
let (_, _, rest) =
3290+
sort::select::partition_at_index(self, index, |a, b| compare(a, b) == Less);
3291+
3292+
if start + 2 > end {
3293+
// the rest slice is of length 0 or 1, already sorted
3294+
return;
3295+
}
3296+
3297+
let index = end - start - 2;
3298+
let (rest, _, _) =
3299+
sort::select::partition_at_index(rest, index, |a, b| compare(a, b) == Less);
3300+
sort::unstable::sort(rest, &mut |a, b| compare(a, b) == Less);
3301+
}
3302+
3303+
/// Partially sorts the slice in ascending order with a key extraction function, **without**
3304+
/// preserving the initial order of equal elements.
3305+
#[unstable(feature = "slice_partial_sort_unstable", issue = "149046")]
3306+
#[inline]
3307+
pub fn partial_sort_unstable_by_key<K, F, R>(&mut self, range: R, mut f: F)
3308+
where
3309+
F: FnMut(&T) -> K,
3310+
K: Ord,
3311+
R: RangeBounds<usize>,
3312+
{
3313+
self.partial_sort_unstable_by(range, |a, b| f(a).cmp(&f(b)));
3314+
}
3315+
32453316
/// Reorders the slice such that the element at `index` is at a sort-order position. All
32463317
/// elements before `index` will be `<=` to this value, and all elements after will be `>=` to
32473318
/// it.

0 commit comments

Comments
 (0)