Skip to content

Commit 182c0cf

Browse files
authored
Merge pull request #255 from bluss/sorted-into-iter
Return an iterator from sorted/sorted_by/sorted_by_key
2 parents 73bb81a + a17ad03 commit 182c0cf

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
@@ -40,6 +40,10 @@ use std::fmt;
4040
use std::hash::Hash;
4141
#[cfg(feature = "use_std")]
4242
use std::fmt::Write;
43+
#[cfg(feature = "use_std")]
44+
type VecIntoIter<T> = ::std::vec::IntoIter<T>;
45+
#[cfg(feature = "use_std")]
46+
use std::iter::FromIterator;
4347

4448
#[macro_use]
4549
mod impl_macros;
@@ -1762,10 +1766,14 @@ pub trait Itertools : Iterator {
17621766
FoldWhile::Continue(acc)
17631767
}
17641768

1765-
/// Collect all iterator elements into a sorted vector in ascending order.
1769+
/// Sort all iterator elements into a new iterator in ascending order.
17661770
///
17671771
/// **Note:** This consumes the entire iterator, uses the
1768-
/// `slice::sort_by()` method and returns the sorted vector.
1772+
/// `slice::sort()` method and returns the result as a new
1773+
/// iterator that owns its elements.
1774+
///
1775+
/// The sorted iterator, if directly collected to a `Vec`, is converted
1776+
/// without any extra copying or allocation cost.
17691777
///
17701778
/// ```
17711779
/// use itertools::Itertools;
@@ -1776,17 +1784,25 @@ pub trait Itertools : Iterator {
17761784
/// "abcdef".chars());
17771785
/// ```
17781786
#[cfg(feature = "use_std")]
1779-
fn sorted(self) -> Vec<Self::Item>
1787+
fn sorted(self) -> VecIntoIter<Self::Item>
17801788
where Self: Sized,
17811789
Self::Item: Ord
17821790
{
1783-
self.sorted_by(Ord::cmp)
1791+
// Use .sort() directly since it is not quite identical with
1792+
// .sort_by(Ord::cmp)
1793+
let mut v = Vec::from_iter(self);
1794+
v.sort();
1795+
v.into_iter()
17841796
}
17851797

1786-
/// Collect all iterator elements into a sorted vector.
1798+
/// Sort all iterator elements into a new iterator in ascending order.
17871799
///
17881800
/// **Note:** This consumes the entire iterator, uses the
1789-
/// `slice::sort_by()` method and returns the sorted vector.
1801+
/// `slice::sort_by()` method and returns the result as a new
1802+
/// iterator that owns its elements.
1803+
///
1804+
/// The sorted iterator, if directly collected to a `Vec`, is converted
1805+
/// without any extra copying or allocation cost.
17901806
///
17911807
/// ```
17921808
/// use itertools::Itertools;
@@ -1797,27 +1813,29 @@ pub trait Itertools : Iterator {
17971813
/// let oldest_people_first = people
17981814
/// .into_iter()
17991815
/// .sorted_by(|a, b| Ord::cmp(&b.1, &a.1))
1800-
/// .into_iter()
18011816
/// .map(|(person, _age)| person);
18021817
///
18031818
/// itertools::assert_equal(oldest_people_first,
18041819
/// vec!["Jill", "Jack", "Jane", "John"]);
18051820
/// ```
18061821
#[cfg(feature = "use_std")]
1807-
fn sorted_by<F>(self, cmp: F) -> Vec<Self::Item>
1822+
fn sorted_by<F>(self, cmp: F) -> VecIntoIter<Self::Item>
18081823
where Self: Sized,
18091824
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
18101825
{
1811-
let mut v: Vec<Self::Item> = self.collect();
1812-
1826+
let mut v = Vec::from_iter(self);
18131827
v.sort_by(cmp);
1814-
v
1828+
v.into_iter()
18151829
}
18161830

1817-
/// Collect all iterator elements into a sorted vector.
1831+
/// Sort all iterator elements into a new iterator in ascending order.
18181832
///
18191833
/// **Note:** This consumes the entire iterator, uses the
1820-
/// `slice::sort_by_key()` method and returns the sorted vector.
1834+
/// `slice::sort_by_key()` method and returns the result as a new
1835+
/// iterator that owns its elements.
1836+
///
1837+
/// The sorted iterator, if directly collected to a `Vec`, is converted
1838+
/// without any extra copying or allocation cost.
18211839
///
18221840
/// ```
18231841
/// use itertools::Itertools;
@@ -1828,22 +1846,20 @@ pub trait Itertools : Iterator {
18281846
/// let oldest_people_first = people
18291847
/// .into_iter()
18301848
/// .sorted_by_key(|x| -x.1)
1831-
/// .into_iter()
18321849
/// .map(|(person, _age)| person);
18331850
///
18341851
/// itertools::assert_equal(oldest_people_first,
18351852
/// vec!["Jill", "Jack", "Jane", "John"]);
18361853
/// ```
18371854
#[cfg(feature = "use_std")]
1838-
fn sorted_by_key<K, F>(self, f: F) -> Vec<Self::Item>
1855+
fn sorted_by_key<K, F>(self, f: F) -> VecIntoIter<Self::Item>
18391856
where Self: Sized,
18401857
K: Ord,
18411858
F: FnMut(&Self::Item) -> K,
18421859
{
1843-
let mut v: Vec<Self::Item> = self.collect();
1844-
1860+
let mut v = Vec::from_iter(self);
18451861
v.sort_by_key(f);
1846-
v
1862+
v.into_iter()
18471863
}
18481864

18491865
/// 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)