How to insert an item into an array at a specific index (JavaScript)?

后端 未结 20 2140
灰色年华
灰色年华 2020-11-21 07:05

I am looking for a JavaScript array insert method, in the style of:

arr.insert(index, item)

Preferably in jQuery, but any JavaScript implem

相关标签:
20条回答
  • 2020-11-21 07:42

    Custom array insert methods

    1. With multiple arguments and chaining support

    /* Syntax:
       array.insert(index, value1, value2, ..., valueN) */
    
    Array.prototype.insert = function(index) {
        this.splice.apply(this, [index, 0].concat(
            Array.prototype.slice.call(arguments, 1)));
        return this;
    };
    

    It can insert multiple elements (as native splice does) and supports chaining:

    ["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(1, 6);
    // ["b", "X", "Y", "Z", "c"]
    

    2. With array-type arguments merging and chaining support

    /* Syntax:
       array.insert(index, value1, value2, ..., valueN) */
    
    Array.prototype.insert = function(index) {
        index = Math.min(index, this.length);
        arguments.length > 1
            && this.splice.apply(this, [index, 0].concat([].pop.call(arguments)))
            && this.insert.apply(this, arguments);
        return this;
    };
    

    It can merge arrays from the arguments with the given array and also supports chaining:

    ["a", "b", "c", "d"].insert(2, "V", ["W", "X", "Y"], "Z").join("-");
    // "a-b-V-W-X-Y-Z-c-d"
    

    DEMO: http://jsfiddle.net/UPphH/

    0 讨论(0)
  • 2020-11-21 07:43

    Another possible solution, with usage of Array#reduce.

    const arr = ["apple", "orange", "raspberry"];
    const arr2 = [1, 2, 4];
    
    const insert = (arr, item, index) =>
      arr.reduce(function(s, a, i) {
        i === index ? s.push(item, a) : s.push(a);
        return s;
      }, []); 
    
    console.log(insert(arr, "banana", 1));
    console.log(insert(arr2, 3, 2))

    0 讨论(0)
  • 2020-11-21 07:43

    A bit of an older thread, but I have to agree with Redu above because splice definitely has a bit of a confusing interface. And the response given by cdbajorin that "it only returns an empty array when the second parameter is 0. If it's greater than 0, it returns the items removed from the array" is, while accurate, proving the point. The function's intent is to splice or as said earlier by Jakob Keller, "to join or connect, also to change. You have an established array that you are now changing which would involve adding or removing elements...." Given that, the return value of the elements, if any, that were removed is awkward at best. And I 100% agree that this method could have been better suited to chaining if it had returned what seems natural, a new array with the spliced elements added. Then you could do things like ["19", "17"].splice(1,0,"18").join("...") or whatever you like with the returned array. The fact that it returns what was removed is just kinda nonsense IMHO. If the intention of the method was to "cut out a set of elements" and that was it's only intent, maybe. It seems like if I don't know what I'm cutting out already though, I probably have little reason to cut those elements out, doesn't it? It would be better if it behaved like concat, map, reduce, slice, etc where a new array is made from the existing array rather than mutating the existing array. Those are all chainable, and that IS a significant issue. It's rather common to chain array manipulation. Seems like the language needs to go one or the other direction and try to stick to it as much as possible. Javascript being functional and less declarative, it just seems like a strange deviation from the norm.

    0 讨论(0)
  • 2020-11-21 07:46

    Taking profit of reduce method as following:

    function insert(arr, val, index) {
        return index >= arr.length 
            ? arr.concat(val)
            : arr.reduce((prev, x, i) => prev.concat(i === index ? [val, x] : x), []);
    }
    

    So at this way we can return a new array (will be a cool functional way - more much better than use push or splice) with the element inserted at index, and if the index is greater than the length of the array it will be inserted at the end.

    0 讨论(0)
  • 2020-11-21 07:47

    You can implement the Array.insert method by doing this:

    Array.prototype.insert = function ( index, item ) {
        this.splice( index, 0, item );
    };
    

    Then you can use it like:

    var arr = [ 'A', 'B', 'D', 'E' ];
    arr.insert(2, 'C');
    
    // => arr == [ 'A', 'B', 'C', 'D', 'E' ]
    
    0 讨论(0)
  • 2020-11-21 07:48

    For proper functional programming and chaining purposes an invention of Array.prototype.insert() is essential. Actually splice could have been perfect if it had returned the mutated array instead of a totally meaningless empty array. So here it goes

    Array.prototype.insert = function(i,...rest){
      this.splice(i,0,...rest)
      return this
    }
    
    var a = [3,4,8,9];
    document.write("<pre>" + JSON.stringify(a.insert(2,5,6,7)) + "</pre>");

    Well ok the above with the Array.prototype.splice() one mutates the original array and some might complain like "you shouldn't modify what doesn't belong to you" and that might turn out to be right as well. So for the public welfare i would like to give another Array.prototype.insert() which doesn't mutate the original array. Here it goes;

    Array.prototype.insert = function(i,...rest){
      return this.slice(0,i).concat(rest,this.slice(i));
    }
    
    var a = [3,4,8,9],
        b = a.insert(2,5,6,7);
    console.log(JSON.stringify(a));
    console.log(JSON.stringify(b));

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