How to rearrange an array by indices array?

前端 未结 9 1923
故里飘歌
故里飘歌 2021-02-01 19:12

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

9条回答
  •  鱼传尺愫
    2021-02-01 19:47

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

提交回复
热议问题