Given an array arr
and an array of indices ind
, I\'d like to rearrange arr
in-place to satisfy the given indices. For exa
This proposal utilizes the answer of Evgeny Kluev.
I made an extension for faster processing, if all elements are already treated, but the index has not reached zero. This is done with an additional variable count
, which counts down for every replaced element. This is used for leaving the main loop if all elements are at right position (count = 0
).
This is helpful for rings, like in the first example with
["A", "B", "C", "D", "E", "F"]
[ 4, 0, 5, 2, 1, 3 ]
index 5: 3 -> 2 -> 5 -> 3
index 4: 1 -> 0 -> 4 -> 1
Both rings are at first two loops rearranged and while each ring has 3 elements, the count
is now zero. This leads to a short circuit for the outer while loop.
function rearrange(values, indices) {
var count = indices.length, index = count, next;
main: while (count && index--) {
next = index;
do {
next = indices[next];
if (next > index) continue main;
} while (next !== index)
do {
next = indices[next];
count--;
values[index] = [values[next], values[next] = values[index]][0];
} while (next !== index)
}
}
function go(values, indices) {
rearrange(values, indices);
console.log(values);
}
go(["A", "B", "C", "D", "E", "F"], [4, 0, 5, 2, 1, 3]);
go(["A", "B", "C", "D", "E", "F"], [1, 2, 0, 4, 5, 3]);
go(["A", "B", "C", "D", "E", "F"], [5, 0, 1, 2, 3, 4]);
go(["A", "B", "C", "D", "E", "F"], [0, 1, 3, 2, 4, 5]);