# Add a "Vec.sorted()" function

**URL:** <https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948>\
**Category:** Uncategorized\
**Created:** [March 9, 2020, 8:33pm UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948 "2020-03-09T20:33:33Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Hocuri](https://avatars.discourse-cdn.com/v4/letter/h/cab0a1/32.png) [@Hocuri](https://internals.rust-lang.org/u/Hocuri)\
**Post date:** [March 9, 2020, 8:33pm UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/1 "2020-03-09T20:33:33Z")

</div>

Many functional languages have a List.sorted() function to enable something like:

```rust
return list
    .do_something()
    .sorted()
    .do_something_else()

```

which looks much nicer than

```rust
let mut l = list.do_something();
sort(&mut l);
return l.do_something_else();

```

and this would be nice for Rust, too.

This could even be easily implemented by oneself, but it would be nicer if it was there by standard:

```rust
trait SortedImpl {
    fn sorted(self) -> Self;
}

impl<E> SortedImpl for Vec<E>
    where E: std::cmp::Ord 
{
    fn sorted(mut self) -> Self {
        self.sort();
        self
    }
}

```

[https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=655714df16aa6c9321bbbb36c1c7bafc](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=655714df16aa6c9321bbbb36c1c7bafc)

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [March 9, 2020, 9:12pm UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/2 "2020-03-09T21:12:26Z")

</div>

I've wanted this many, many times. 👍

---

<div class="post-metadata">

**Author:** ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)\
**Post date:** [March 9, 2020, 9:43pm UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/3 "2020-03-09T21:43:29Z")

</div>

You can get this with [`Itertools::sorted`](https://docs.rs/itertools/0.9.0/itertools/trait.Itertools.html#method.sorted), relying on the fact that collecting `vec::IntoIter` to `Vec` is [specialized](https://github.com/rust-lang/rust/blob/3dbade652ed8ebac70f903e01f51cd92c4e4302c/src/liballoc/vec.rs#L2074) into a no-op.

```rust
vec.into_iter().sorted().collect()

```

Depending on what your `do_something()` and `do_something_else()` are doing, this `sorted()` might even be preferable.

---

<div class="post-metadata">

**Author:** ![hyeonu](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/hyeonu/32/2162_2.png) [@hyeonu](https://internals.rust-lang.org/u/hyeonu)\
**Post date:** [March 10, 2020, 2:44am UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/4 "2020-03-10T02:44:44Z")

</div>

For me `vec.sorted()` _sounds_ like to clone the original vector, sort, and return it. Kotlin has such convention.

---

<div class="post-metadata">

**Author:** ![chriskrycho](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/chriskrycho/32/12576_2.png) [@chriskrycho](https://internals.rust-lang.org/u/chriskrycho)\
**Post date:** [March 10, 2020, 3:35am UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/5 "2020-03-10T03:35:20Z")

</div>

Swift has the same convention: `sort` would sort in place and `sorted` would return a sorted clone of the item. The convention is _quite_ useful, though it's late enough in the life of Rust's standard library that I'm not sure it could be adopted widely the way it is in Swift.

---

<div class="post-metadata">

**Author:** ![dan\_t](https://avatars.discourse-cdn.com/v4/letter/d/eada6e/32.png) [@dan\_t](https://internals.rust-lang.org/u/dan_t)\
**Post date:** [March 10, 2020, 8:38am UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/6 "2020-03-10T08:38:44Z")

</div>

I assumed the same and was quite surprised about the move. And I never used Kotlin or Swift.

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [March 10, 2020, 9:48am UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/7 "2020-03-10T09:48:08Z")

</div>

Yes, I still think this is a good idea:

> [@Pre-RFC-ish: add Vec::sorted and friends](https://internals.rust-lang.org/t/pre-rfc-ish-add-vec-sorted-and-friends/7454):
>
> Hi! What do folks think about adding impl Vec\<T\> { fn sorted(self) -\> Vec\<T\> where T: Ord { let mut this = self; this.sort(); this } // and seven other `sort` flavors? } to the stdlib? This method would allow to replace let mut deps\_metadata = cx.dep\_targets(unit) .iter() .map(|dep| metadata\_of(dep, cx, metas)) .collect::\<Vec\<\_\>\>(); deps\_metadata.sort(); with a more fluent version: let deps\_metadata = cx.dep\_targets(unit) .iter() .m…

---

<div class="post-metadata">

**Author:** ![Hocuri](https://avatars.discourse-cdn.com/v4/letter/h/cab0a1/32.png) [@Hocuri](https://internals.rust-lang.org/u/Hocuri)\
**Post date:** [March 10, 2020, 11:29am UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/8 "2020-03-10T11:29:48Z")

</div>

> [@hyeonu](#):
>
> For me `vec.sorted()` _sounds_ like to clone the original vector, sort, and return it. Kotlin has such convention.

I'd say that it sounds like it returns a sorted version of the vector. In other languages, this means that the original vector has to be cloned to avoid side effects. This has the disadvantage that functional style often has worse performance.

But in Rust we have the possibility to do this without cloning it (by moving) so that we can have functional style without the performance overhead.

If you do want to clone it (because you still need the original vector), you can still do `.clone().sorted()`. And the best thing is: If you forget the `.clone()`, the compiler will throw an error ("use of moved value", I think).

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [March 10, 2020, 1:13pm UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/9 "2020-03-10T13:13:08Z")

</div>

> [@Hocuri](#):
>
> But in Rust we have the possibility to do this without cloning it (by moving) so that we can have functional style without the performance overhead.
> 
> If you do want to clone it (because you still need the original vector), you can still do `.clone().sorted()` . And the best thing is: If you forget the `.clone()` , the compiler will throw an error ("use of moved value", I think).

Exactly. I would expect this method to consume `self` and produce a new vector.

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [March 10, 2020, 1:19pm UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/10 "2020-03-10T13:19:39Z")

</div>

For better visibility, here's how would Cargo look if we had sorted: [https://github.com/matklad/cargo/commit/3ff7ccc82dc9b555c25e7df97e1afde648810399](https://github.com/matklad/cargo/commit/3ff7ccc82dc9b555c25e7df97e1afde648810399). In majority of cases, `sorted` leads to nicer code than `sort`.

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [March 10, 2020, 2:34pm UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/11 "2020-03-10T14:34:50Z")

</div>

That diff looks great. Anyone up for making the PR?

---

<div class="post-metadata">

**Author:** ![toc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/toc/32/6692_2.png) [@toc](https://internals.rust-lang.org/u/toc)\
**Post date:** [March 10, 2020, 3:54pm UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/12 "2020-03-10T15:54:47Z")

</div>

I ran this same change with itertools. I agree this looks nicer, I'm not 100% convinced it should be in std.

> <https://github.com/adeodatus/cargo/commit/c64cf60eaec460daf3ef3b482a6ed442805a61d5>

---

<div class="post-metadata">

**Author:** ![Keats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/keats/32/1715_2.png) [@Keats](https://internals.rust-lang.org/u/Keats)\
**Post date:** [March 11, 2020, 4:09pm UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/13 "2020-03-11T16:09:19Z")

</div>

I think this is common and simple enough that it should be in std

---

<div class="post-metadata">

**Author:** ![toc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/toc/32/6692_2.png) [@toc](https://internals.rust-lang.org/u/toc)\
**Post date:** [March 11, 2020, 5:05pm UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/14 "2020-03-11T17:05:43Z")

</div>

The other thing I notice about the itertools approach is the transformation to vec is a little magical. Embedding a `.sorted()` in an iterator chain with itertools is nice, the proposed change looks like

```rust
x.iter().filter(...).collect::<Vec<_>>().sorted().into_iter().map(...)

```

in those cases.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [March 12, 2020, 7:29pm UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/15 "2020-03-12T19:29:09Z")

</div>

I assume this would imply also adding `Vec::sorted_by` and `Vec::sorted_by_key`?

It being on Vec _is_ a nice way to avoid the "does it collect, does it return a Vec or an iterator, [is it lazy](https://internals.rust-lang.org/t/add-binaryheap-into-iter-sorted/9749)" etc questions that happen with any iterator version.

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [March 12, 2020, 9:14pm UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/16 "2020-03-12T21:14:25Z")

</div>

It also is a nice way out of Iterator being in libcore. You need liballoc for sorted iterator adaptor.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [March 12, 2020, 10:07pm UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/17 "2020-03-12T22:07:22Z")

</div>

> [@matklad](#):
>
> liballoc for sorted

Oh yeah, we also need to ask whether there should also be `Vec::sorted_unstable{_by{_key}}`...

---

<div class="post-metadata">

**Author:** ![skysch](https://avatars.discourse-cdn.com/v4/letter/s/f05b48/32.png) [@skysch](https://internals.rust-lang.org/u/skysch)\
**Post date:** [March 13, 2020, 3:53pm UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/18 "2020-03-13T15:53:34Z")

</div>

However, if you're sorting in `Vec`, you don't add very much by chaining `.sorted()`, since you can avoid it altogether by doing something like `.collect<BTreeSet<_>>()` instead. It's only useful if you intend to actually end on a `Vec`.

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [March 13, 2020, 3:57pm UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/19 "2020-03-13T15:57:59Z")

</div>

That's a pattern I suspect people wouldn't automatically think of. Might be a good argument for a `.collect_sorted()` on iterators.

---

<div class="post-metadata">

**Author:** ![RustyYato](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rustyyato/32/13627_2.png) [@RustyYato](https://internals.rust-lang.org/u/RustyYato)\
**Post date:** [March 13, 2020, 4:08pm UTC](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948/20 "2020-03-13T16:08:13Z")

</div>

> [@skysch](#):
>
> avoid it altogether by doing something like `.collect<BTreeSet<_>>()` instead

That is semantically different, because it gets rid of duplicates.

[Next page](https://internals.rust-lang.org/t/add-a-vec-sorted-function/11948.md?page=2)
