Move an array element from one array position to another

后端 未结 30 2477
渐次进展
渐次进展 2020-11-22 08:36

I\'m having a hard time figuring out how to move an array element. For example, given the following:

var arr = [ \'a\', \'b\', \'c\', \'d\', \'e\'];
<         


        
相关标签:
30条回答
  • 2020-11-22 09:01

    const move = (from, to, ...a) =>from === to ? a : (a.splice(to, 0, ...a.splice(from, 1)), a);
    const moved = move(0, 2, ...['a', 'b', 'c']);
    console.log(moved)

    0 讨论(0)
  • 2020-11-22 09:02

    I think the best way is define a new property for Arrays

    Object.defineProperty(Array.prototype, 'move', {
        value: function (old_index, new_index) {
            while (old_index < 0) {
                old_index += this.length;
            }
            while (new_index < 0) {
                new_index += this.length;
            }
            if (new_index >= this.length) {
                let k = new_index - this.length;
                while ((k--) + 1) {
                    this.push(undefined);
                }
            }
            this.splice(new_index, 0, this.splice(old_index, 1)[0]);
            return this;
        }
    });
    
    console.log([10, 20, 30, 40, 50].move(0, 1));  // [20, 10, 30, 40, 50]
    console.log([10, 20, 30, 40, 50].move(0, 2));  // [20, 30, 10, 40, 50]
    
    0 讨论(0)
  • 2020-11-22 09:04

    The splice method of Array might help: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice

    Just keep in mind it might be relatively expensive since it has to actively re-index the array.

    0 讨论(0)
  • 2020-11-22 09:04

    One approach would be to create a new array with the pieces in the order you want, using the slice method.

    Example

    var arr = [ 'a', 'b', 'c', 'd', 'e'];
    var arr2 = arr.slice(0,1).concat( ['d'] ).concat( arr.slice(2,4) ).concat( arr.slice(4) );
    
    • arr.slice(0,1) gives you ['a']
    • arr.slice(2,4) gives you ['b', 'c']
    • arr.slice(4) gives you ['e']
    0 讨论(0)
  • 2020-11-22 09:04

        let oldi, newi, arr;
        
        if(newi !== oldi) {
          let el = this.arr.splice(oldi, 1);
          if(newi > oldi && newi === (this.arr.length + 2)) {
            this.arr.push("");
          }
          this.arr.splice(newi, 0, el);
          if(newi > oldi && newi === (this.arr.length + 2)) {
            this.arr.pop();
          }
        }

    0 讨论(0)
  • 2020-11-22 09:05

    I ended up combining two of these to work a little better when moving both small and large distances. I get fairly consistent results, but this could probably be tweaked a little bit by someone smarter than me to work differently for different sizes, etc.

    Using some of the other methods when moving objects small distances was significantly faster (x10) than using splice. This might change depending on the array lengths though, but it is true for large arrays.

    function ArrayMove(array, from, to) {
        if ( Math.abs(from - to) > 60) {
            array.splice(to, 0, array.splice(from, 1)[0]);
        } else {
            // works better when we are not moving things very far
            var target = array[from];
            var inc = (to - from) / Math.abs(to - from);
            var current = from;
            for (; current != to; current += inc) {
                array[current] = array[current + inc];
            }
            array[to] = target;    
        }
    }
    

    http://jsperf.com/arraymove-many-sizes

    0 讨论(0)
提交回复
热议问题