with no ambition to compete with any of the proposed solutions

```
function dualperm(u,v)
un=unique(v)
du=mapreduce(b->findall(==(b),u),vcat, un)
dv=mapreduce(b->findall(==(b),v),vcat, un)
u2v=last.(sort(tuple.(du,dv), by=first))
v2u=first.(sort(tuple.(du,dv), by=last))
(u2v, v2u)
end
julia> v[dualperm(u,v)[1]]==u
true
julia>
julia> u[dualperm(u,v)[2]]==v
true
```

this is much better

```
function dp(u,v)
l=length(v)
tv=last.(sort(collect(zip(v,1:l))))
tu=last.(sort(collect(zip(u,1:l))))
last.(sort(tuple.(tu,tv)))
end
```

```
julia> v=[1,2,1,3,3,2,4]
7-element Vector{Int64}:
1
2
1
3
3
2
4
julia> u=[2,1,3,3,1,4,2]
7-element Vector{Int64}:
2
1
3
3
1
4
2
julia> function dperm(u,v)
l=length(v)
last.(sort(tuple.(last.(sort(collect(zip(u,1:l)))),last.(sort(collect(zip(v,1:l)))))))
end
dperm (generic function with 1 method)
julia> @btime v[dperm(u,v)]
288.627 ns (11 allocations: 1.44 KiB)
7-element Vector{Int64}:
2
1
3
3
1
4
2
julia> @btime v[sortperm(v)[Base.invperm(sortperm(u))]]
430.808 ns (7 allocations: 592 bytes)
7-element Vector{Int64}:
2
1
3
3
1
4
2
```