# The sort！function

**URL:** <https://discourse.julialang.org/t/the-sort-function/108261>\
**Category:** General Usage\
**Tags:** question\
**Created:** [January 2, 2024, 1:18pm UTC](https://discourse.julialang.org/t/the-sort-function/108261 "2024-01-02T13:18:58Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![jiang\_ming\_zhang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jiang_ming_zhang/32/204063_2.png) [@jiang\_ming\_zhang](https://discourse.julialang.org/u/jiang_ming_zhang)\
**Post date:** [January 2, 2024, 1:18pm UTC](https://discourse.julialang.org/t/the-sort-function/108261/1 "2024-01-02T13:18:58Z")

</div>

In matlab, with the code

```julia
[table, ind]= sort(table)

```

we get not only the sorted ‘table’, but also the ‘ind’ that contains the information of the positions of the sorted elements in the original table.

What is the counterpart in julia?

With ‘sort!’, we only get the table, but not ind.

---

<div class="post-metadata">

**Author:** ![John\_Gibson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/john_gibson/32/5321_2.png) [@John\_Gibson](https://discourse.julialang.org/u/John_Gibson)\
**Post date:** [January 2, 2024, 1:22pm UTC](https://discourse.julialang.org/t/the-sort-function/108261/2 "2024-01-02T13:22:05Z")

</div>

I think `sortperm` is what you’re looking for.

```julia
help?> sortperm
search: sortperm sortperm! partialsortperm partialsortperm! isconcretetype

  sortperm(A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])

  Return a permutation vector or array I that puts A[I] in sorted order along the given
  dimension. If A has more than one dimension, then the dims keyword argument must be
  specified. The order is specified using the same keywords as sort!. The permutation is
  guaranteed to be stable even if the sorting algorithm is unstable: the indices of equal
  elements will appear in ascending order.

```

---

<div class="post-metadata">

**Author:** ![jiang\_ming\_zhang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jiang_ming_zhang/32/204063_2.png) [@jiang\_ming\_zhang](https://discourse.julialang.org/u/jiang_ming_zhang)\
**Post date:** [January 2, 2024, 1:54pm UTC](https://discourse.julialang.org/t/the-sort-function/108261/3 "2024-01-02T13:54:37Z")

</div>

thanks a lot! But it is not as convenient as matlab. In matlab, we need only one line

```julia
[table, ind]= sort(table)

```

Here in julia, we need two lines

```julia
ind=sortperm(table)
table = table(ind)

```

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [January 2, 2024, 2:39pm UTC](https://discourse.julialang.org/t/the-sort-function/108261/4 "2024-01-02T14:39:00Z")

</div>

> [@jiang\_ming\_zhang](#):
>
> Here in julia, we need two lines

Semicolons can help to write two expressions in 1 line:

```julia
ind = sortperm(table); table = table[ind]

```

I don’t know if it’s closer to the MATLAB variable model to do `table .= table[ind]` to sort `table` in-place, but in Julia you may need `table` to remain the same instance that might already be shared with other variables. It performs about the same, and there is a `permute!(table, ind)` that does the same thing; you can’t optimize to elementwise `table .= getindex.((table,), ind)` because it overwrites elements that weren’t reordered yet.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [January 2, 2024, 2:53pm UTC](https://discourse.julialang.org/t/the-sort-function/108261/5 "2024-01-02T14:53:21Z")

</div>

> [@Benny](#):
>
> `ind = sortperm(table); table = table[ind]`

The number of lines is one thing, but does this imply some superfluous work on the part of Julia? Could it be more efficient to sort the array and produce the indices simultaneously?

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [January 2, 2024, 2:59pm UTC](https://discourse.julialang.org/t/the-sort-function/108261/6 "2024-01-02T14:59:51Z")

</div>

That was assuming the sort must use `ind`. The more performant equivalent way would be `ind = sortperm(table); sort!(table)`. I don’t know if it’ll be any faster if those were sorted together, or generally multiple arrays being reordered with respect to sorting one of them.

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [January 2, 2024, 3:05pm UTC](https://discourse.julialang.org/t/the-sort-function/108261/7 "2024-01-02T15:05:05Z")

</div>

```julia
sort(tuple.(table, eachindex(table)), by=first)

```

```julia
collect(zip(sort(tuple.(table, eachindex(table)), by=first)...))

```

```julia
table, ind = (fs(t)=(table[t],t))(sortperm(table))

table, ind = (t=sortperm(table); (table[t],t))

```

---

<div class="post-metadata">

**Author:** ![mike.ingold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike.ingold/32/203749_2.png) [@mike.ingold](https://discourse.julialang.org/u/mike.ingold)\
**Post date:** [January 2, 2024, 4:01pm UTC](https://discourse.julialang.org/t/the-sort-function/108261/8 "2024-01-02T16:01:01Z")

</div>

> [@jiang\_ming\_zhang](#):
>
> But it is not as convenient as matlab. In matlab, we need only one line
> 
> ```julia
> [table, ind]= sort(table)
> 
> ```
> 
> Here in julia, we need two lines
> 
> ```julia
> ind=sortperm(table)
> table = table(ind)
> 
> ```

If this desired syntax isn’t directly replicable but is particularly important to you, you can absolutely define your own convenience functions, e.g.:

```julia
function matlabsort(tbl)
    ind = sortperm(tbl)
    return (tbl[ind], ind)
end

```

Julia is not intended to be a 1:1 direct replacement for any other language, including Matlab. There are always going to be functions or features which don’t directly translate, and this isn’t inherently a bug, just a difference in implementation.

This seems to be one of those Matlab-isms where the returns captured from a function depend on the left-hand side of the assignment operation, i.e. `tbl = sort(tbl)` captures only the sorted table but `[tbl,ind] = sort(tbl)` captures both the table and the permuted indices. This style isn’t consistent with how code is written in Julia, where instead you’d always have to write something like `(tbl, _) = sort(tbl)` to disregard the unneeded returns.

In any event, as a breaking change there’s a 0% chance that modifying `Base.sort` like this would be accepted prior to some theoretical future v2.0 of Julia. If someone felt strongly about enabling this, there’s a few potentials ways forward: submit the code as a PR to Julia ( [Pull requests · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pulls)), write up your own package that includes this implementation and share it to the General registry ( [How to develop a Julia package (julialang.org)](https://julialang.org/contribute/developing_package/) ), or if you only care to have them defined for your own non-shared code just keep a file of such convenience functions handy and import them as needed.

---

<div class="post-metadata">

**Author:** ![mike.ingold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike.ingold/32/203749_2.png) [@mike.ingold](https://discourse.julialang.org/u/mike.ingold)\
**Post date:** [January 2, 2024, 4:19pm UTC](https://discourse.julialang.org/t/the-sort-function/108261/9 "2024-01-02T16:19:02Z")

</div>

Looks like the second option I referenced, writing your own Matlab-style package, has already been attempted at least once: [GitHub - juliamatlab/MatLang: Matlab’s language functions written in Julia](https://github.com/juliamatlab/MatLang). The repo shows no commits in the past 4 years, but the `Project.toml` shows compatibility with at least Julia v1.0, and it seems to add just fine for me in a fresh Pluto environment.

It has a [sortM function](https://juliamatlab.github.io/MatLang/dev/functions/Matrices_and_Arrays/#MatLang.sortM-Tuple) defined such that

```julia
using MatLang

v = randn(5)
# v = [-0.14698, 0.279868, -0.216259, -0.699488, 0.933226]

tbl, ind = sortM(v, I=true)
# tbl = [-0.699488, -0.216259, -0.14698, 0.279868, 0.933226]
# ind = [4, 3, 1, 2, 5]

```
