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]);