Skip to content

Commit a17ad03

Browse files
committed
FEAT: Return an iterator from sorted/sorted_by/sorted_by_key
1 parent dd7fe2a commit a17ad03

File tree

3 files changed

+46
-25
lines changed

3 files changed

+46
-25
lines changed

src/free.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#[cfg(feature = "use_std")]
77
use std::fmt::Display;
88
use std::iter::{self, Zip};
9+
#[cfg(feature = "use_std")]
10+
type VecIntoIter<T> = ::std::vec::IntoIter<T>;
11+
912
#[cfg(feature = "use_std")]
1013
use Itertools;
1114

@@ -211,9 +214,11 @@ pub fn join<I>(iterable: I, sep: &str) -> String
211214
iterable.into_iter().join(sep)
212215
}
213216

214-
/// Collect all the iterable's elements into a sorted vector in ascending order.
217+
/// Sort all iterator elements into a new iterator in ascending order.
218+
///
219+
/// `IntoIterator` enabled version of [`iterable.sorted()`][1].
215220
///
216-
/// `IntoIterator` enabled version of `iterable.sorted()`.
221+
/// [1]: trait.Itertools.html#method.sorted
217222
///
218223
/// ```
219224
/// use itertools::sorted;
@@ -222,7 +227,7 @@ pub fn join<I>(iterable: I, sep: &str) -> String
222227
/// assert_equal(sorted("rust".chars()), "rstu".chars());
223228
/// ```
224229
#[cfg(feature = "use_std")]
225-
pub fn sorted<I>(iterable: I) -> Vec<I::Item>
230+
pub fn sorted<I>(iterable: I) -> VecIntoIter<I::Item>
226231
where I: IntoIterator,
227232
I::Item: Ord
228233
{

src/lib.rs

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ use std::fmt;
3838
use std::hash::Hash;
3939
#[cfg(feature = "use_std")]
4040
use std::fmt::Write;
41+
#[cfg(feature = "use_std")]
42+
type VecIntoIter<T> = ::std::vec::IntoIter<T>;
43+
#[cfg(feature = "use_std")]
44+
use std::iter::FromIterator;
4145

4246
#[macro_use]
4347
mod impl_macros;
@@ -1609,10 +1613,14 @@ pub trait Itertools : Iterator {
16091613
FoldWhile::Continue(acc)
16101614
}
16111615

1612-
/// Collect all iterator elements into a sorted vector in ascending order.
1616+
/// Sort all iterator elements into a new iterator in ascending order.
16131617
///
16141618
/// **Note:** This consumes the entire iterator, uses the
1615-
/// `slice::sort_by()` method and returns the sorted vector.
1619+
/// `slice::sort()` method and returns the result as a new
1620+
/// iterator that owns its elements.
1621+
///
1622+
/// The sorted iterator, if directly collected to a `Vec`, is converted
1623+
/// without any extra copying or allocation cost.
16161624
///
16171625
/// ```
16181626
/// use itertools::Itertools;
@@ -1623,17 +1631,25 @@ pub trait Itertools : Iterator {
16231631
/// "abcdef".chars());
16241632
/// ```
16251633
#[cfg(feature = "use_std")]
1626-
fn sorted(self) -> Vec<Self::Item>
1634+
fn sorted(self) -> VecIntoIter<Self::Item>
16271635
where Self: Sized,
16281636
Self::Item: Ord
16291637
{
1630-
self.sorted_by(Ord::cmp)
1638+
// Use .sort() directly since it is not quite identical with
1639+
// .sort_by(Ord::cmp)
1640+
let mut v = Vec::from_iter(self);
1641+
v.sort();
1642+
v.into_iter()
16311643
}
16321644

1633-
/// Collect all iterator elements into a sorted vector.
1645+
/// Sort all iterator elements into a new iterator in ascending order.
16341646
///
16351647
/// **Note:** This consumes the entire iterator, uses the
1636-
/// `slice::sort_by()` method and returns the sorted vector.
1648+
/// `slice::sort_by()` method and returns the result as a new
1649+
/// iterator that owns its elements.
1650+
///
1651+
/// The sorted iterator, if directly collected to a `Vec`, is converted
1652+
/// without any extra copying or allocation cost.
16371653
///
16381654
/// ```
16391655
/// use itertools::Itertools;
@@ -1644,27 +1660,29 @@ pub trait Itertools : Iterator {
16441660
/// let oldest_people_first = people
16451661
/// .into_iter()
16461662
/// .sorted_by(|a, b| Ord::cmp(&b.1, &a.1))
1647-
/// .into_iter()
16481663
/// .map(|(person, _age)| person);
16491664
///
16501665
/// itertools::assert_equal(oldest_people_first,
16511666
/// vec!["Jill", "Jack", "Jane", "John"]);
16521667
/// ```
16531668
#[cfg(feature = "use_std")]
1654-
fn sorted_by<F>(self, cmp: F) -> Vec<Self::Item>
1669+
fn sorted_by<F>(self, cmp: F) -> VecIntoIter<Self::Item>
16551670
where Self: Sized,
16561671
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
16571672
{
1658-
let mut v: Vec<Self::Item> = self.collect();
1659-
1673+
let mut v = Vec::from_iter(self);
16601674
v.sort_by(cmp);
1661-
v
1675+
v.into_iter()
16621676
}
16631677

1664-
/// Collect all iterator elements into a sorted vector.
1678+
/// Sort all iterator elements into a new iterator in ascending order.
16651679
///
16661680
/// **Note:** This consumes the entire iterator, uses the
1667-
/// `slice::sort_by_key()` method and returns the sorted vector.
1681+
/// `slice::sort_by_key()` method and returns the result as a new
1682+
/// iterator that owns its elements.
1683+
///
1684+
/// The sorted iterator, if directly collected to a `Vec`, is converted
1685+
/// without any extra copying or allocation cost.
16681686
///
16691687
/// ```
16701688
/// use itertools::Itertools;
@@ -1675,22 +1693,20 @@ pub trait Itertools : Iterator {
16751693
/// let oldest_people_first = people
16761694
/// .into_iter()
16771695
/// .sorted_by_key(|x| -x.1)
1678-
/// .into_iter()
16791696
/// .map(|(person, _age)| person);
16801697
///
16811698
/// itertools::assert_equal(oldest_people_first,
16821699
/// vec!["Jill", "Jack", "Jane", "John"]);
16831700
/// ```
16841701
#[cfg(feature = "use_std")]
1685-
fn sorted_by_key<K, F>(self, f: F) -> Vec<Self::Item>
1702+
fn sorted_by_key<K, F>(self, f: F) -> VecIntoIter<Self::Item>
16861703
where Self: Sized,
16871704
K: Ord,
16881705
F: FnMut(&Self::Item) -> K,
16891706
{
1690-
let mut v: Vec<Self::Item> = self.collect();
1691-
1707+
let mut v = Vec::from_iter(self);
16921708
v.sort_by_key(f);
1693-
v
1709+
v.into_iter()
16941710
}
16951711

16961712
/// Collect all iterator elements into one of two

tests/test_std.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,19 +269,19 @@ fn sorted_by() {
269269
let sc = [3, 4, 1, 2].iter().cloned().sorted_by(|&a, &b| {
270270
a.cmp(&b)
271271
});
272-
assert_eq!(sc, vec![1, 2, 3, 4]);
272+
it::assert_equal(sc, vec![1, 2, 3, 4]);
273273

274274
let v = (0..5).sorted_by(|&a, &b| a.cmp(&b).reverse());
275-
assert_eq!(v, vec![4, 3, 2, 1, 0]);
275+
it::assert_equal(v, vec![4, 3, 2, 1, 0]);
276276
}
277277

278278
#[test]
279279
fn sorted_by_key() {
280280
let sc = [3, 4, 1, 2].iter().cloned().sorted_by_key(|&x| x);
281-
assert_eq!(sc, vec![1, 2, 3, 4]);
281+
it::assert_equal(sc, vec![1, 2, 3, 4]);
282282

283283
let v = (0..5).sorted_by_key(|&x| -x);
284-
assert_eq!(v, vec![4, 3, 2, 1, 0]);
284+
it::assert_equal(v, vec![4, 3, 2, 1, 0]);
285285
}
286286

287287
#[test]

0 commit comments

Comments
 (0)