# Is there a more elegant solution than \`sortperm(sortperm(...))\`

**URL:** <https://discourse.julialang.org/t/is-there-a-more-elegant-solution-than-sortperm-sortperm/35015>\
**Category:** Performance\
**Tags:** question\
**Created:** [February 22, 2020, 1:35pm UTC](https://discourse.julialang.org/t/is-there-a-more-elegant-solution-than-sortperm-sortperm/35015 "2020-02-22T13:35:37Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![pfarndt](https://avatars.discourse-cdn.com/v4/letter/p/8dc957/32.png) [@pfarndt](https://discourse.julialang.org/u/pfarndt)\
**Post date:** [February 22, 2020, 1:35pm UTC](https://discourse.julialang.org/t/is-there-a-more-elegant-solution-than-sortperm-sortperm/35015/1 "2020-02-22T13:35:37Z")

</div>

Say I have two vectors of identifiers - the second one being a shuffled version of the first one - like this:

```julia
using Random, Test
a = [randstring(5) for _ in 1:20]
b = shuffle(a)

```

and now I want to loop through `a` such that the elements occur in the order given by `b`, i.e. I need a permutation `v` such that `a[v] == b`.

The solution I came up with is:

```julia
v = sortperm(a)[sortperm(sortperm(b))]
@test a[v] == b

```

Is there a more elegant than the above solution?

I do not care about performance right now - but I could imagine that the `sortperm(sortperm(.))` construct will not behave well for longer vectors - so there might be also a more performant solution.

---

<div class="post-metadata">

**Author:** ![tamasgal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamasgal/32/27946_2.png) [@tamasgal](https://discourse.julialang.org/u/tamasgal)\
**Post date:** [February 22, 2020, 1:52pm UTC](https://discourse.julialang.org/t/is-there-a-more-elegant-solution-than-sortperm-sortperm/35015/2 "2020-02-22T13:52:04Z")

</div>

I am curious about your original problem. Why do you do it like this, if I may ask?

Given your question, I’d suggest to simply loop over `b` (with different starting indices).

I am asking to avoid an [XY-Problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)

---

<div class="post-metadata">

**Author:** ![pfarndt](https://avatars.discourse-cdn.com/v4/letter/p/8dc957/32.png) [@pfarndt](https://discourse.julialang.org/u/pfarndt)\
**Post date:** [February 22, 2020, 2:15pm UTC](https://discourse.julialang.org/t/is-there-a-more-elegant-solution-than-sortperm-sortperm/35015/3 "2020-02-22T14:15:08Z")

</div>

OK - a is intact not just a vector of identifiers but a vector of `struct`s - the identifier is just one field in this `struct`. The order I want to go through them is given by a vector `b` of just these identifiers. The order is computed from data which is not presented in `a`, therefore I cannot just do a `sort!(a, ...)`.

So therefore I need this permutation `v` and can for instance:

```julia
for k in 1:length(b)
  do_something_with(a[v[k]])
end

```

in the order given by `b`.

---

<div class="post-metadata">

**Author:** ![retrosnub](https://avatars.discourse-cdn.com/v4/letter/r/ecb155/32.png) [@retrosnub](https://discourse.julialang.org/u/retrosnub)\
**Post date:** [February 22, 2020, 2:24pm UTC](https://discourse.julialang.org/t/is-there-a-more-elegant-solution-than-sortperm-sortperm/35015/4 "2020-02-22T14:24:20Z")

</div>

```julia
v = indexin(b, a)

```

but why not write your loop as

```julia
for v in b
    do_something_with(a[v])
end

```

?

---

<div class="post-metadata">

**Author:** ![pfarndt](https://avatars.discourse-cdn.com/v4/letter/p/8dc957/32.png) [@pfarndt](https://discourse.julialang.org/u/pfarndt)\
**Post date:** [February 22, 2020, 2:41pm UTC](https://discourse.julialang.org/t/is-there-a-more-elegant-solution-than-sortperm-sortperm/35015/5 "2020-02-22T14:41:27Z")

</div>

This is exactly what I was looking for. Thanks

---

<div class="post-metadata">

**Author:** ![pfarndt](https://avatars.discourse-cdn.com/v4/letter/p/8dc957/32.png) [@pfarndt](https://discourse.julialang.org/u/pfarndt)\
**Post date:** [February 22, 2020, 2:50pm UTC](https://discourse.julialang.org/t/is-there-a-more-elegant-solution-than-sortperm-sortperm/35015/6 "2020-02-22T14:50:57Z")

</div>

The permutation `v = indexin(b, a)` is the one I am looking for. The loop should probably be:

```julia
for k in v
  do_something_with(a[k])
end

```

---

<div class="post-metadata">

**Author:** ![retrosnub](https://avatars.discourse-cdn.com/v4/letter/r/ecb155/32.png) [@retrosnub](https://discourse.julialang.org/u/retrosnub)\
**Post date:** [February 22, 2020, 3:38pm UTC](https://discourse.julialang.org/t/is-there-a-more-elegant-solution-than-sortperm-sortperm/35015/7 "2020-02-22T15:38:36Z")

</div>

Yes, my bad.  
I was thinking of `a` as a `Dict`, which might be worth considering if you are doing many indexing-using-identifiers operations.
