如何在特定索引(JavaScript)的数组中插入项?

时间:2009-02-25 14:29:31

标签: javascript jquery arrays insert

我正在寻找一种JavaScript数组插入方法,风格为:

arr.insert(index, item)

最好在jQuery中,但此时任何JavaScript实现都会这样做。

20 个答案:

答案 0 :(得分:4026)

你想要的是原生数组对象上的 splice 函数。

arr.splice(index, 0, item);会在item处将arr插入到指定的索引处(首先删除0个项目,也就是说,它只是一个插入内容。)

在这个例子中,我们将创建一个数组并将一个元素添加到索引2中:

var arr = [];
arr[0] = "Jani";
arr[1] = "Hege";
arr[2] = "Stale";
arr[3] = "Kai Jim";
arr[4] = "Borge";

console.log(arr.join());
arr.splice(2, 0, "Lene");
console.log(arr.join());

答案 1 :(得分:248)

您可以通过以下方式实施Array.insert方法:

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

然后你就可以使用它:

var arr = [ 'A', 'B', 'D', 'E' ];
arr.insert(2, 'C');

// => arr == [ 'A', 'B', 'C', 'D', 'E' ]

答案 2 :(得分:85)

除了拼接之外,您可以使用这种方法,它不会改变原始数组,但会创建一个带有添加项的新数组。你应该尽可能避免变异。我在这里使用ES6传播运营商。

const items = [1, 2, 3, 4, 5]

const insert = (arr, index, newItem) => [
  // part of the array before the specified index
  ...arr.slice(0, index),
  // inserted item
  newItem,
  // part of the array after the specified index
  ...arr.slice(index)
]

const result = insert(items, 1, 10)

console.log(result)
// [1, 10, 2, 3, 4, 5]

这可以用来添加多个项目,稍微调整一下这个函数,以便为新项目使用rest操作符,并将其传播到返回的结果中

const items = [1, 2, 3, 4, 5]

const insert = (arr, index, ...newItems) => [
  // part of the array before the specified index
  ...arr.slice(0, index),
  // inserted items
  ...newItems,
  // part of the array after the specified index
  ...arr.slice(index)
]

const result = insert(items, 1, 10, 20)

console.log(result)
// [1, 10, 20, 2, 3, 4, 5]

答案 3 :(得分:71)

自定义数组insert方法

1。使用多个参数和链接支持

/* 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;
};

它可以插入多个元素(如本机splice所做的那样)并支持链接:

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

2。使用数组类型参数合并和链接支持

/* 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;
};

它可以将参数中的数组与给定数组合并,并且还支持链接:

["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/

答案 4 :(得分:32)

如果您想一次将多个元素插入数组,请查看此Stack Overflow答案:A better way to splice an array into an array in javascript

这里有一些功能来说明这两个例子:

function insertAt(array, index) {
    var arrayToInsert = Array.prototype.splice.apply(arguments, [2]);
    return insertArrayAt(array, index, arrayToInsert);
}

function insertArrayAt(array, index, arrayToInsert) {
    Array.prototype.splice.apply(array, [index, 0].concat(arrayToInsert));
    return array;
}

最后这里是一个jsFiddle,所以你可以自己看看它:http://jsfiddle.net/luisperezphd/Wc8aS/

这就是你使用这些功能的方法:

// if you want to insert specific values whether constants or variables:
insertAt(arr, 1, "x", "y", "z");

// OR if you have an array:
var arrToInsert = ["x", "y", "z"];
insertArrayAt(arr, 1, arrToInsert);

答案 5 :(得分:17)

对于正确的函数编程和链接目的,Array.prototype.insert()的发明是必不可少的。实际上,如果它已经返回变异数组而不是一个完全没有意义的空数组,则splice可能是完美的。所以这就是



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>");
&#13;
&#13;
&#13;

好吧,上面的Array.prototype.splice()改变了原来的阵列,有些人可能会抱怨&#34;你不应该修改不属于你的东西&#34;而且这也可能是正确的。因此,对于公益事业,我想提供另一个Array.prototype.insert(),它不会改变原始数组。在这里;

&#13;
&#13;
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));
&#13;
&#13;
&#13;

答案 6 :(得分:11)

我建议在这种情况下使用纯 JavaScript ,JavaScript中也没有插入方法,但我们有一个内置数组方法为你工作,它被称为拼接 ......

让我们看看拼接() ......

  

splice()方法通过删除来更改数组的内容   现有元素和/或添加新元素。

好的,想象一下我们下面有这个数组:

const arr = [1, 2, 3, 4, 5];

我们可以像这样删除3

arr.splice(arr.indexOf(3), 1);

它将返回3,但如果我们现在检查arr,我们有:

[1, 2, 4, 5]

到目前为止,这么好,但我们如何使用splice向数组添加新元素? 让我们把3放在arr ......

arr.splice(2, 0, 3);

让我们看看我们做了什么......

我们再次使用拼接,但这次是第二个参数,我们传递 0 ,意味着我们想删除没有项目,但同时,我们添加第三个参数是3将在第二个索引处添加...

您应该知道,我们可以同时删除添加,例如现在我们可以这样做:

arr.splice(2, 2, 3);

将在索引2处删除 2项,然后在索引2处添加 3 ,结果将为:

[1, 2, 3, 5];

这显示了拼接中每个项目的工作原理:

  

array.splice(start,deleteCount,item1,item2,item3 ...)

答案 7 :(得分:6)

将单个元素附加到特定索引

//Append at specific position(here at index 1)
arrName.splice(1, 0,'newName1');
//1: index number, 0: number of element to remove, newName1: new element


//Append at specific position (here at index 3)
arrName[3] = 'newName1';

在特定索引处附加多个元素

//Append from index number 1
arrName.splice(1, 0,'newElemenet1', 'newElemenet2', 'newElemenet3');
//1: index number from where append start, 
//0: number of element to remove, 
//newElemenet1,2,3: new elements

答案 8 :(得分:6)

另一种可能的解决方案,使用Array#reduce

var arr = ["apple", "orange", "raspberry"],
    arr2 = [1, 2, 4];

function insert(arr, item, index) {
    arr = arr.reduce(function(s, a, i) {
      i == index ? s.push(item, a) : s.push(a);
      return s;
    }, []);   
    console.log(arr);
}

insert(arr, "banana", 1);
insert(arr2, 3, 2);

答案 9 :(得分:5)

即使已经回答了这个问题,我还是将这个说明添加到另一种方法中。

我想将一个已知数字项放入一个数组中,放入特定位置,因为它们来自一个“关联数组”(即一个对象),根据定义,它不能保证是按排序顺序。我希望生成的数组是一个对象数组,但是由于数组保证了它们的顺序,所以对象在数组中按特定的顺序排列。所以我这样做了。

首先是源对象,一个从PostgreSQL中检索的JSONB字符串。我想让它按每个子对象中的“order”属性排序。

var jsonb_str = '{"one": {"abbr": "", "order": 3}, "two": {"abbr": "", "order": 4}, "three": {"abbr": "", "order": 5}, "initialize": {"abbr": "init", "order": 1}, "start": {"abbr": "", "order": 2}}';

var jsonb_obj = JSON.parse(jsonb_str);

由于对象中的节点数是已知的,我首先创建一个具有指定长度的数组:

var obj_length = Object.keys(jsonb_obj).length;
var sorted_array = new Array(obj_length);

然后迭代对象,将新创建的临时对象放入数组中的所需位置,而不进行任何“排序”。

for (var key of Object.keys(jsonb_obj)) {
  var tobj = {};
  tobj[key] = jsonb_obj[key].abbr;

  var position = jsonb_obj[key].order - 1;
  sorted_array[position] = tobj;
}

console.dir(sorted_array);

答案 10 :(得分:3)

我试过这个并且工作正常!

var initialArr = ["India","China","Japan","USA"];
initialArr.splice(index, 0, item);

索引是您要插入或删除元素的位置。 0,即第二参数定义要从中删除的索引的元素数 item是要在数组中创建的新条目。它可以是一个或多个。

initialArr.splice(2, 0, "Nigeria");
initialArr.splice(2, 0, "Australia","UK");

答案 11 :(得分:3)

有两种方法:

const array = [ 'My', 'name', 'Hamza' ];

array.splice(2, 0, 'is');

console.log("Method 1 : ", array.join(" "));

OR

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

const array = [ 'My', 'name', 'Hamza' ];
array.insert(2, 'is');

console.log("Method 2 : ", array.join(" "));

答案 12 :(得分:3)

解决方案和性能

今天(2020.04.24),我对选定的大型和小型阵列解决方案进行了测试。我在Chrome 81.0,Safari 13.1,Firefox 75.0的MacOs High Sierra 10.13.6上进行了测试。

结论

对于所有浏览器

  • 对于小型阵列,基于slicereduce(D,E,F)的非就地解决方案通常比就地解决方案快10到100倍
  • 对于大型阵列,基于splice(AI,BI,CI)的就地解决方案最快(有时约为100倍-但取决于阵列大小)
  • 对于小型阵列,BI解决方案最慢
  • 对于大阵列E解决方案最慢

enter image description here

详细信息

测试分为两类:就地解决方案(AI,BI,CI)和非就地解决方案(D,E,F),并且针对两种情况进行了测试

  • 测试包含10个元素的数组-您可以HERE运行它
  • 测试具有1.000.000元素的数组-您可以运行HERE

经测试的代码显示在以下代码段中

jsfiddle

function AI(arr, i, el) {
  arr.splice(i, 0, el);
  return arr;
}

function BI(arr, i, el) {
  Array.prototype.splice.apply(arr, [i, 0, el]);
  return arr;
}

function CI(arr, i, el) {
  Array.prototype.splice.call(arr, i, 0, el);
  return arr;
}

function D(arr, i, el) {
  return arr.slice(0, i).concat(el, arr.slice(i));
}

function E(arr, i, el) {
  return [...arr.slice(0, i), el, ...arr.slice(i)]
}

function F(arr, i, el) {
  return arr.reduce((s, a, j)=> (j-i ? s.push(a) : s.push(el, a), s), []);
}



// -------------
// TEST
// -------------

let arr = ["a", "b", "c", "d", "e", "f"];

let log = (n, f) => {
  let a = f([...arr], 3, "NEW");
  console.log(`${n}: [${a}]`);
};

log('AI', AI);
log('BI', BI);
log('CI', CI);
log('D', D);
log('E', E);
log('F', F);
This snippet only presents tested code (it not perform tests)

Chrome上的小型阵列的结果示例如下

enter image description here

答案 13 :(得分:2)

任何人仍然对此有疑问,并尝试了以上所有选项,但从未成功。我在分享我的解决方案,是要考虑到您不想明确声明对象与数组的属性。

function isIdentical(left, right){
    return JSON.stringify(left) === JSON.stringify(right);
}

function contains(array, obj){
    let count = 0;
    array.map((cur) => {
          if(this.isIdentical(cur, obj)) count++;
    });
    return count > 0;
}

这是对引用数组进行迭代并将其与要检查的对象进行比较的组合,将它们都转换为字符串,然后在匹配时进行迭代。然后,您可以数数。这可以改善,但这是我解决的地方。希望这会有所帮助。

答案 14 :(得分:2)

采用减少方法的利润如下:

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

因此,通过这种方式,我们可以返回一个新数组(这将是一种很酷的功能方式-比使用push或splice更好),并将元素插入到index处,如果index大于数组的长度,则返回将插入到末尾。

答案 15 :(得分:2)

不可插入

如果您需要就地插入数组,那么使用splice方法无疑是最佳答案。

但是,如果您正在寻找一个不可变的函数,该函数返回一个新的更新数组,而不是在插入时对原始数组进行突变,则可以使用以下函数。

function insert(array, index) {
  const items = Array.prototype.slice.call(arguments, 2);

  return [].concat(array.slice(0, index), items, array.slice(index));
}

const list = ['one', 'two', 'three'];

const list1 = insert(list, 0, 'zero'); // Insert single item
const list2 = insert(list, 3, 'four', 'five', 'six'); // Insert multiple


console.log('Original list: ', list);
console.log('Inserted list1: ', list1);
console.log('Inserted list2: ', list2);

注意::这是ES2015之前的一种实现方式,因此它适用于新旧浏览器。

如果您使用的是ES6,则也可以尝试rest parameters;参见this答案。

答案 16 :(得分:1)

有点旧的线程,但是我必须同意上面的Redu,因为拼接肯定有一些令人困惑的接口。 cdbajorin给出的响应是:“仅当第二个参数为0时,它才返回一个空数组。如果它大于0,则它返回从数组中删除的项”,这是正确的。该函数的目的是进行拼接,或者如Jakob Keller先前所述,“进行连接或连接,也进行更改。您现在要更改的已建立数组将涉及添加或删除元素。...”返回的元素的值(如果有的话)充其量是尴尬的。我100%同意,如果此方法返回了看起来很自然的结果,那么它可能会更适合于链接,这是一个添加了拼接元素的新数组。然后,您可以对返回的数组执行诸如[“ 19”,“ 17”]。splice(1,0,“ 18”)。join(“ ...”)之类的操作。它返回已删除内容的事实只是个废话恕我直言。如果该方法的目的是“切出一组元素”,那仅仅是目的。似乎,如果我不知道要切出什么,我可能没有什么理由要切掉那些元素,不是吗?如果它的行为像concat,map,reduce,slice等,那将是更好的做法,其中从现有数组中创建一个新数组,而不是对现有数组进行突变。这些都是可链接的,这是一个重要的问题。链数组操作相当普遍。似乎该语言需要朝着另一个方向发展,并尽可能地坚持下去。 Javascript具有功能性且声明性较差,似乎偏离了规范。

答案 17 :(得分:1)

我不喜欢安全,我使用它

   Array.prototype.Insert = function (item, before) {
        if (!item) return;
        if (before == null || before < 0 || before > this.length - 1) {
            this.push(item);
            return;
        }
        this.splice(before, 0,item );
    }
    
    
   var t = ["a","b"]
   
   t.Insert("v",1)
    
    console.log(t )

答案 18 :(得分:0)

这是我在一个应用程序中使用的工作功能。

这将检查项目是否退出

let ifExist = (item, strings = [ '' ], position = 0) => {
     // output into an array with empty string. Important just in case their is no item. 
    let output = [ '' ];
    // check to see if the item that will be positioned exist.
    if (item) {
        // output should equal to array of strings. 
        output = strings;
       // use splice in order to break the array. 
       // use positition param to state where to put the item
       // and 0 is to not replace an index. Item is the actual item we are placing at the prescribed position. 
        output.splice(position, 0, item);
    }
    //empty string is so we do not concatenate with comma or anything else. 
    return output.join("");
};

然后在下面称呼它。

ifExist("friends", [ ' ( ', ' )' ], 1)}  // output: ( friends )
ifExist("friends", [ ' - '], 1)}  // output:  - friends 
ifExist("friends", [ ':'], 0)}  // output:   friends: 

答案 19 :(得分:0)

Array#splice()是必经之路,除非您真的想避免对数组进行变异。给定2个数组arr1arr2,可按照以下方法将arr2的内容插入第一个元素之后的arr1中:

const arr1 = ['a', 'd', 'e'];
const arr2 = ['b', 'c'];

arr1.splice(1, 0, ...arr2); // arr1 now contains ['a', 'b', 'c', 'd', 'e']

如果您担心要更改数组(例如,如果使用Immutable.js),则可以改用slice(),不要与带有{p的splice()混淆。

const arr3 = [...arr1.slice(0, 1), ...arr2, ...arr1.slice(1)];