@@ -3153,6 +3153,105 @@ pub trait Itertools: Iterator {
31533153 self . k_smallest_by ( k, k_smallest:: key_to_cmp ( key) )
31543154 }
31553155
3156+ /// Sort the k smallest elements into a new iterator, in ascending order, relaxing the amount of memory required.
3157+ ///
3158+ /// **Note:** This consumes the entire iterator, and returns the result
3159+ /// as a new iterator that owns its elements. If the input contains
3160+ /// less than k elements, the result is equivalent to `self.sorted()`.
3161+ ///
3162+ /// This is guaranteed to use `2 * k * sizeof(Self::Item) + O(1)` memory
3163+ /// and `O(n + k log k)` time, with `n` the number of elements in the input,
3164+ /// meaning it uses more memory than the minimum obtained by [`k_smallest`](Itertools::k_smallest)
3165+ /// but achieves linear time in the number of elements.
3166+ ///
3167+ /// The sorted iterator, if directly collected to a `Vec`, is converted
3168+ /// without any extra copying or allocation cost.
3169+ ///
3170+ /// **Note:** This is functionally-equivalent to `self.sorted().take(k)`
3171+ /// but much more efficient.
3172+ ///
3173+ /// ```
3174+ /// use itertools::Itertools;
3175+ ///
3176+ /// // A random permutation of 0..15
3177+ /// let numbers = vec![6, 9, 1, 14, 0, 4, 8, 7, 11, 2, 10, 3, 13, 12, 5];
3178+ ///
3179+ /// let five_smallest = numbers
3180+ /// .into_iter()
3181+ /// .k_smallest_relaxed(5);
3182+ ///
3183+ /// itertools::assert_equal(five_smallest, 0..5);
3184+ /// ```
3185+ #[ cfg( feature = "use_alloc" ) ]
3186+ fn k_smallest_relaxed ( self , k : usize ) -> VecIntoIter < Self :: Item >
3187+ where
3188+ Self : Sized ,
3189+ Self :: Item : Ord ,
3190+ {
3191+ self . k_smallest_relaxed_by ( k, Ord :: cmp)
3192+ }
3193+
3194+ /// Sort the k smallest elements into a new iterator using the provided comparison, relaxing the amount of memory required.
3195+ ///
3196+ /// The sorted iterator, if directly collected to a `Vec`, is converted
3197+ /// without any extra copying or allocation cost.
3198+ ///
3199+ /// This corresponds to `self.sorted_by(cmp).take(k)` in the same way that
3200+ /// [`k_smallest_relaxed`](Itertools::k_smallest_relaxed) corresponds to `self.sorted().take(k)`,
3201+ /// in both semantics and complexity.
3202+ ///
3203+ /// ```
3204+ /// use itertools::Itertools;
3205+ ///
3206+ /// // A random permutation of 0..15
3207+ /// let numbers = vec![6, 9, 1, 14, 0, 4, 8, 7, 11, 2, 10, 3, 13, 12, 5];
3208+ ///
3209+ /// let five_smallest = numbers
3210+ /// .into_iter()
3211+ /// .k_smallest_relaxed_by(5, |a, b| (a % 7).cmp(&(b % 7)).then(a.cmp(b)));
3212+ ///
3213+ /// itertools::assert_equal(five_smallest, vec![0, 7, 14, 1, 8]);
3214+ /// ```
3215+ #[ cfg( feature = "use_alloc" ) ]
3216+ fn k_smallest_relaxed_by < F > ( self , k : usize , cmp : F ) -> VecIntoIter < Self :: Item >
3217+ where
3218+ Self : Sized ,
3219+ F : FnMut ( & Self :: Item , & Self :: Item ) -> Ordering ,
3220+ {
3221+ k_smallest:: k_smallest_relaxed_general ( self , k, cmp) . into_iter ( )
3222+ }
3223+
3224+ /// Return the elements producing the k smallest outputs of the provided function, relaxing the amount of memory required.
3225+ ///
3226+ /// The sorted iterator, if directly collected to a `Vec`, is converted
3227+ /// without any extra copying or allocation cost.
3228+ ///
3229+ /// This corresponds to `self.sorted_by_key(key).take(k)` in the same way that
3230+ /// [`k_smallest_relaxed`](Itertools::k_smallest_relaxed) corresponds to `self.sorted().take(k)`,
3231+ /// in both semantics and complexity.
3232+ ///
3233+ /// ```
3234+ /// use itertools::Itertools;
3235+ ///
3236+ /// // A random permutation of 0..15
3237+ /// let numbers = vec![6, 9, 1, 14, 0, 4, 8, 7, 11, 2, 10, 3, 13, 12, 5];
3238+ ///
3239+ /// let five_smallest = numbers
3240+ /// .into_iter()
3241+ /// .k_smallest_relaxed_by_key(5, |n| (n % 7, *n));
3242+ ///
3243+ /// itertools::assert_equal(five_smallest, vec![0, 7, 14, 1, 8]);
3244+ /// ```
3245+ #[ cfg( feature = "use_alloc" ) ]
3246+ fn k_smallest_relaxed_by_key < F , K > ( self , k : usize , key : F ) -> VecIntoIter < Self :: Item >
3247+ where
3248+ Self : Sized ,
3249+ F : FnMut ( & Self :: Item ) -> K ,
3250+ K : Ord ,
3251+ {
3252+ self . k_smallest_relaxed_by ( k, k_smallest:: key_to_cmp ( key) )
3253+ }
3254+
31563255 /// Sort the k largest elements into a new iterator, in descending order.
31573256 ///
31583257 /// The sorted iterator, if directly collected to a `Vec`, is converted
@@ -3243,6 +3342,94 @@ pub trait Itertools: Iterator {
32433342 self . k_largest_by ( k, k_smallest:: key_to_cmp ( key) )
32443343 }
32453344
3345+ /// Sort the k largest elements into a new iterator, in descending order, relaxing the amount of memory required.
3346+ ///
3347+ /// The sorted iterator, if directly collected to a `Vec`, is converted
3348+ /// without any extra copying or allocation cost.
3349+ ///
3350+ /// It is semantically equivalent to [`k_smallest_relaxed`](Itertools::k_smallest_relaxed)
3351+ /// with a reversed `Ord`.
3352+ ///
3353+ /// ```
3354+ /// use itertools::Itertools;
3355+ ///
3356+ /// // A random permutation of 0..15
3357+ /// let numbers = vec![6, 9, 1, 14, 0, 4, 8, 7, 11, 2, 10, 3, 13, 12, 5];
3358+ ///
3359+ /// let five_largest = numbers
3360+ /// .into_iter()
3361+ /// .k_largest_relaxed(5);
3362+ ///
3363+ /// itertools::assert_equal(five_largest, vec![14, 13, 12, 11, 10]);
3364+ /// ```
3365+ #[ cfg( feature = "use_alloc" ) ]
3366+ fn k_largest_relaxed ( self , k : usize ) -> VecIntoIter < Self :: Item >
3367+ where
3368+ Self : Sized ,
3369+ Self :: Item : Ord ,
3370+ {
3371+ self . k_largest_relaxed_by ( k, Self :: Item :: cmp)
3372+ }
3373+
3374+ /// Sort the k largest elements into a new iterator using the provided comparison, relaxing the amount of memory required.
3375+ ///
3376+ /// The sorted iterator, if directly collected to a `Vec`, is converted
3377+ /// without any extra copying or allocation cost.
3378+ ///
3379+ /// Functionally equivalent to [`k_smallest_relaxed_by`](Itertools::k_smallest_relaxed_by)
3380+ /// with a reversed `Ord`.
3381+ ///
3382+ /// ```
3383+ /// use itertools::Itertools;
3384+ ///
3385+ /// // A random permutation of 0..15
3386+ /// let numbers = vec![6, 9, 1, 14, 0, 4, 8, 7, 11, 2, 10, 3, 13, 12, 5];
3387+ ///
3388+ /// let five_largest = numbers
3389+ /// .into_iter()
3390+ /// .k_largest_relaxed_by(5, |a, b| (a % 7).cmp(&(b % 7)).then(a.cmp(b)));
3391+ ///
3392+ /// itertools::assert_equal(five_largest, vec![13, 6, 12, 5, 11]);
3393+ /// ```
3394+ #[ cfg( feature = "use_alloc" ) ]
3395+ fn k_largest_relaxed_by < F > ( self , k : usize , mut cmp : F ) -> VecIntoIter < Self :: Item >
3396+ where
3397+ Self : Sized ,
3398+ F : FnMut ( & Self :: Item , & Self :: Item ) -> Ordering ,
3399+ {
3400+ self . k_smallest_relaxed_by ( k, move |a, b| cmp ( b, a) )
3401+ }
3402+
3403+ /// Return the elements producing the k largest outputs of the provided function, relaxing the amount of memory required.
3404+ ///
3405+ /// The sorted iterator, if directly collected to a `Vec`, is converted
3406+ /// without any extra copying or allocation cost.
3407+ ///
3408+ /// Functionally equivalent to [`k_smallest_relaxed_by_key`](Itertools::k_smallest_relaxed_by_key)
3409+ /// with a reversed `Ord`.
3410+ ///
3411+ /// ```
3412+ /// use itertools::Itertools;
3413+ ///
3414+ /// // A random permutation of 0..15
3415+ /// let numbers = vec![6, 9, 1, 14, 0, 4, 8, 7, 11, 2, 10, 3, 13, 12, 5];
3416+ ///
3417+ /// let five_largest = numbers
3418+ /// .into_iter()
3419+ /// .k_largest_relaxed_by_key(5, |n| (n % 7, *n));
3420+ ///
3421+ /// itertools::assert_equal(five_largest, vec![13, 6, 12, 5, 11]);
3422+ /// ```
3423+ #[ cfg( feature = "use_alloc" ) ]
3424+ fn k_largest_relaxed_by_key < F , K > ( self , k : usize , key : F ) -> VecIntoIter < Self :: Item >
3425+ where
3426+ Self : Sized ,
3427+ F : FnMut ( & Self :: Item ) -> K ,
3428+ K : Ord ,
3429+ {
3430+ self . k_largest_relaxed_by ( k, k_smallest:: key_to_cmp ( key) )
3431+ }
3432+
32463433 /// Consumes the iterator and return an iterator of the last `n` elements.
32473434 ///
32483435 /// The iterator, if directly collected to a `VecDeque`, is converted
0 commit comments