【问题标题】:How to insert an item into an array at a specific index (JavaScript)如何将项目插入到特定索引处的数组中(JavaScript)
【发布时间】:2010-10-09 19:52:16
【问题描述】:

我正在寻找一种 JavaScript 数组插入方法,样式如下:

arr.insert(index, item)

最好使用 jQuery,但此时任何 JavaScript 实现都可以。

【问题讨论】:

  • 请注意,JQuery 是一个 DOM 和事件操作库,而不是它自己的语言。它与数组操作无关。
  • api.jquery.com/jQuery.inArray 与 DOM 或事件无关。 jQuery 已经发展成为一个用于浏览器 JS 开发的混合工具包,这导致人们期望它拥有一个适用于所有事物的方法。
  • @Tim,但它仍然不是自己的语言(仍然有一些问题,例如“如何在 jQuery 中对两个数字求和”)
  • @Victor 不,永远不会。 jQuery 是有用且相关的,但它已经过时了。
  • 我很生气这个问题的标题和它的页面标题不同(jQuery 与 JS)。在搜索结果中的显示方式不同。

标签: javascript jquery arrays


【解决方案1】:

使用Array.prototype.splice() 是实现此目的的简单方法

const numbers = ['one', 'two', 'four', 'five']
numbers.splice(2, 0, 'three');

console.log(numbers)

阅读更多关于Array.prototype.splice()here

【讨论】:

    【解决方案2】:

    splice()方法在添加元素时通常会接收三个参数:

    1. 要添加项目的数组的索引
    2. 要删除的项目数,在本例中为 0
    3. 要添加的元素

    let array = ['item 1', 'item 2', 'item 3'],
        insertAtIndex = 0,
        itemsToRemove = 0;
        
    array.splice(insertAtIndex, itemsToRemove, 'insert this string on index 0');
    
    console.log(array);

    【讨论】:

      【解决方案3】:

      我是这样做的:

      const insert = (what, where, index) => 
        ([...where.slice(0, index), what , ...where.slice(index, where.length)]);
      

      const insert = (what, where, index) =>
        ([...where.slice(0, index), what , ...where.slice(index, where.length)]);
        
      const list = [1, 2, 3, 4, 5, 6];
      const newList = insert('a', list, 2);
      
      console.log(newList.indexOf('a') === 2);

      【讨论】:

        【解决方案4】:

        这是现代(Typescript 功能)方式:

        export const insertItemInList = <T>(
          arr: T[],
          index: number,
          newItem: T
        ): T[] => [...arr.slice(0, index), newItem, ...arr.slice(index)]
        

        【讨论】:

          【解决方案5】:

          为了正确的函数式编程和链接目的,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>");

          嗯,好的,上面带有Array.prototype.splice() 的数组改变了原始数组,有些人可能会抱怨“你不应该修改不属于你的东西”,这也可能是正确的。所以为了公益,我想再给一个Array.prototype.insert(),它不会改变原数组。就这样吧;

          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,则返回从数组中删除的项。鉴于您要添加到原型,并且 splice 改变了原始数组,我认为“正确的函数式编程”不属于 splice 附近的任何地方。
          • 我们这里说的是insert,Array.prototype.splice()的第二个参数必须为零。它返回的内容除了“我没有删除任何东西”之外没有任何意义,因为我们用它来插入一个项目,所以我们已经有了这些信息。如果您不想改变原始数组,那么您可以使用两个 Array.prototype.slice() 和一个 Array.prototype.concat() 操作来做同样的事情。这取决于你。
          • 您的第二个实现是整个页面中最干净的,您的投票数为零。请拿走我的,继续做好工作。 (你应该避免改变原型,但你已经知道了)
          • 我觉得值得一提的是rest参数是new ECMA 6th (developer.mozilla.org/en/docs/Web/JavaScript/Reference/…)
          【解决方案6】:

          如果您想一次将多个元素插入到数组中,请查看此 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);
          

          【讨论】:

          • insertAt() 创建单元素arrayToInsert 后调用insertArrayAt() 会不会更好?这样可以避免重复相同的代码。
          • 这是一个很好的例子,说明何时使用“应用”
          • 我在这个方法中添加了一个 removeCount 参数,以利用 splice 的能力来删除该索引处的项目: Array.prototype.splice.apply(array, [index, removeCount || 0].concat (arrayToInsert));
          【解决方案7】:

          我喜欢一点安全感,我用这个:

             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 )

          【讨论】:

          • 你说喜欢安全,建议修改基本原型!逻辑?没有
          • 是的..这是我对安全的定义..哈哈
          【解决方案8】:

          不可变插入

          如果您需要就地插入数组,使用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);

          注意:这是ES6 之前的方式,因此它适用于较旧和较新的浏览器。

          如果你使用的是 ES6,那么你也可以试试rest parameters;见this answer

          【讨论】:

            【解决方案9】:

            解决方案和性能

            今天(2020.04.24)我为大小阵列选择的解决方案进行测试。我在 Chrome 81.0、Safari 13.1 和 Firefox 75.0 上的 macOS v10.13.6 (High Sierra) 上对它们进行了测试。

            结论

            适用于所有浏览器

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

            详情

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

            • 测试一个有 10 个元素的数组 - 你可以运行它here
            • 测试一个包含 1,000,000 个元素的数组 - 你可以运行它here

            经过测试的代码显示在下面的sn-p中:

            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)

            Google Chrome 上的小数组的示例结果如下:

            【讨论】:

            • 答案没有解决 OP 的问题。
            • @kabirbaidhya 实际上在这个答案中你可以找到很多 OP 问题的解决方案,但是这个答案的附加价值是它们之间的性能比较 - 我希望很多人会觉得它有用
            • 也许,您可能需要稍微重构您的答案,以便用户可以直观地先看到可能的解决方案,然后再看到它们对性能的影响。它看起来主要集中在性能方面。
            【解决方案10】:

            这里有两种方法:

            const array = [ 'My', 'name', 'Hamza' ];
            
            array.splice(2, 0, 'is');
            
            console.log("Method 1: ", array.join(" "));

            或者

            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(" "));

            【讨论】:

              【解决方案11】:

              我不得不同意 Redu 的回答,因为 splice() 肯定有一些令人困惑的界面。而 cdbajorin 给出的响应“仅在第二个参数为 0 时返回一个空数组。如果大于 0,则返回从数组中删除的项目”,虽然准确,但证明了这一点。

              该功能的目的是拼接,或者正如 Jakob Keller 之前所说,“加入或连接,也可以改变。

              您现在正在更改一个已建立的数组,这将涉及添加或删除元素......”鉴于此,被删除的元素(如果有的话)的返回值充其量是尴尬的。我 100%同意这个方法可能更适合链接,如果它返回看起来很自然的东西,一个添加了拼接元素的新数组。然后你可以做类似 ["19", "17"].splice(1,0, "18").join("...") 或任何你喜欢的返回数组。

              它返回已删除内容的事实只是一种无稽之谈恕我直言。如果该方法的目的是“切出一组元素”并且这是它的唯一意图,也许。看起来如果我不知道我已经剪掉了什么,我可能没有理由剪掉这些元素,不是吗?

              如果它的行为类似于 concat()、map()、reduce()、slice() 等,其中一个新数组是由现有数组创建的,而不是对现有数组进行变异,那会更好。这些都是可链接的,这 一个重要的问题。链式数组操作相当常见。

              似乎语言需要朝着一个或另一个方向发展,并尽可能地坚持下去。 JavaScript 是函数式的,声明性较少,这似乎是一种奇怪的偏离规范。

              【讨论】:

                【解决方案12】:

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

                这会检查一个项目是否存在:

                let ifExist = (item, strings = [ '' ], position = 0) => {
                     // Output into an array with an empty string. Important just in case their isn't any item.
                    let output = [ '' ];
                    // Check to see if the item that will be positioned exist.
                    if (item) {
                        // Output should be equal to an array of strings.
                        output = strings;
                       // Use splice() in order to break the array.
                       // Use positional parameters 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:
                

                【讨论】:

                  【解决方案13】:

                  reduce方法的获利如下:

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

                  因此,通过这种方式,我们可以返回一个新数组(将是一种很酷的功能方式 - 比使用 pushsplice 更好),其中元素插入到索引处,如果索引大于数组的长度,它将被插入到末尾。

                  【讨论】:

                    【解决方案14】:

                    任何对此问题仍有疑问并尝试了以前答案中的所有选项但从未得到它的人。我正在分享我的解决方案,这是考虑到您不想明确声明对象与数组的属性。

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

                    这是迭代引用数组并将其与您要检查的对象进行比较的组合,将它们都转换为字符串,然后在匹配时进行迭代。然后你就可以数数了。这可以改进,但这是我安顿下来的地方。

                    【讨论】:

                      【解决方案15】:

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

                      // Append at a 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 a 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
                      

                      【讨论】:

                      • 值得注意的是,arrName[3] 不会附加,它会覆盖。
                      • 它将元素添加到现有数组中而不是覆盖,例如:let arrName = ['xxx', 'yyy', 'zzz']; arrName.splice(1, 0,'aaa', 'bbb', 'ccc');打印 arrName 后
                      • 如果 arrName 有超过 3 个元素,您将覆盖第 3 个元素,而不是追加。还是我看错了?
                      • 如果我们在中间插入一个元素,它会移动下一个元素而不是覆盖。请说明您的问题,您需要什么。拿一个数组(例子)和你需要的输出。请评论我
                      • 如果数组只有 3 个元素,@Srikrushna arrName[3] = 'newName1'; 将追加。如果索引 3 中有一个元素,它将被替换。如果要在末尾追加,最好使用arrName.push('newName1');
                      【解决方案16】:

                      在这种情况下,我建议使用纯 JavaScript。 JavaScript 中也没有任何插入方法,但我们有一个方法是 内置数组 方法,它可以为您完成这项工作。这叫拼接...

                      让我们看看什么是 splice()...

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

                      好的,假设我们在下面有这个数组:

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

                      我们可以像这样删除3

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

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

                      [1, 2, 4, 5]
                      

                      到目前为止,一切都很好,但是我们如何使用拼接将新元素添加到数组中?

                      让我们把 3 放回 arr...

                      arr.splice(2, 0, 3);
                      

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

                      我们再次使用splice,但是这次对于第二个参数,我们传递了0,这意味着我们不想删除任何项目,但同时,我们添加第三个参数,即将在第二个索引处添加的 3...

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

                      arr.splice(2, 2, 3);
                      

                      这将删除索引 2 处的 两个项目。然后在索引 2 处添加 3,结果将是:

                      [1, 2, 3, 5];
                      

                      这显示了 splice 中的每个项目是如何工作的:

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

                      【讨论】:

                      • 感谢您以后解释我建议对数组值使用非数字数字,以显示示例。例如:arr.splice(2, 0, 3) 与 arr.splice(2, 0, "C")。读者更容易理解哪个参数映射到值部分,哪个参数映射到索引部分。谢谢!
                      【解决方案17】:

                      另一种可能的解决方案,使用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))

                      【讨论】:

                        【解决方案18】:

                        我试过了,效果很好!

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

                        索引是要插入或删除元素的位置。

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

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

                        【讨论】:

                        • 简单地复制粘贴上面的答案。这并没有为问题增加任何价值。您可以添加新答案或评论现有答案。请尝试贡献一些新的东西。我们不想破坏这个社区
                        【解决方案19】:

                        除了拼接之外,您可以使用这种不会改变原始数组的方法,但它会创建一个包含添加项的新数组。您通常应该尽可能避免突变。我在这里使用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]

                        【讨论】:

                        • 这是一种安全的好方法吗?我问是因为这看起来如此优雅和简洁,但没有其他答案涉及这一点。大部分都是修改原型对象!
                        • @HarshKanchina 这可能是因为大多数答案都是 ES6 之前的,但是根据我的经验,这种方法现在很常见
                        • 这种方法总是比拼接更慢更差。不要被漂亮的糖语法或其他被误导的开发人员中的流行所迷惑(*cough* gafi *cough*)。分配一个全新的数组并丢弃旧数组比修改原始数组要慢得多。如果您需要一份副本,请在splice() 之前致电slice()。永远不要将 ES6 用于如此琐碎的事情,这些事情可以用其他 API 做得更好、更干净。
                        • 你应该解释为什么你应该避免突变。慢吗?如果是这样,慢多少?额外的“麻烦”值得吗?
                        • @JackG 不要忘记slice() 将分配一个新数组,事实上,splice() 也分配了一个新数组,因为它返回一个包含已删除项目的数组(一个空数组在这种情况下)。在这些情况下运行基准测试表明拼接速度更快(约 30%),但我们处于每秒数百万次操作的范围内,因此除非您的应用程序正在执行大量这些操作在一个紧密的循环中,它不会有任何区别。
                        【解决方案20】:

                        尽管这个问题已经得到解答,我还是添加了这个注释作为替代方法。

                        我想将 已知数量 的项目放入一个数组中的特定位置,因为它们来自一个“关联数组”(即一个对象),根据定义,它不能保证是以排序的顺序。我希望得到的数组是一个对象数组,但是对象在数组中的顺序是特定的,因为数组保证了它们的顺序。所以我就这么做了。

                        首先是源对象,从 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);
                        

                        【讨论】:

                          【解决方案21】:

                          您希望在原生数组对象上使用 splice 函数。

                          arr.splice(index, 0, item);会在arr中指定index处插入item(先删除0项,也就是插入)。

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

                          var arr = [];
                          arr[0] = "Jani";
                          arr[1] = "Hege";
                          arr[2] = "Stale";
                          arr[3] = "Kai Jim";
                          arr[4] = "Borge";
                          
                          console.log(arr.join()); // Jani,Hege,Stale,Kai Jim,Borge
                          arr.splice(2, 0, "Lene");
                          console.log(arr.join()); // Jani,Hege,Lene,Stale,Kai Jim,Borge

                          【讨论】:

                          • 谢谢,我以为我会因为问而感到愚蠢,但现在我知道答案了,我不知道!当一个更易于搜索的术语被普遍用于相同的功能时,他们到底为什么决定将其命名为 splice?!
                          • @tags2k: 因为这个函数不仅仅是插入项目而且它的名字已经在 perl 中建立了?
                          • 拼接可以插入,但经常不能。例如:arr.splice(2,3) 将删除从索引 2 开始的 3 个元素。如果不传递第 3 个....第 N 个参数,则不会插入任何内容。所以insert() 这个名字也不公平。
                          • 我认为“拼接”这个词是有道理的。拼接意味着加入或连接,也意味着改变。您有一个已建立的数组,您现在正在“更改”这将涉及添加或删除元素。您指定从数组中的哪个位置开始,然后指定要删除多少旧项目(如果有),最后,可以选择要添加的新元素列表。拼接当然也是一个很棒的科幻术语。
                          【解决方案22】:

                          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']
                          
                          console.log(arr1)

                          如果您担心改变数组(例如,如果使用 Immutable.js),您可以改用 slice(),不要将 splice()'p' 混淆。

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

                          【讨论】:

                            【解决方案23】:

                            您可以通过这样做来实现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' ]
                            

                            【讨论】:

                            • 要插入多个项目,您可以使用Array.prototype.insert = function (index, items) { this.splice.apply(this, [index, 0].concat(items)); }
                            • 向数组添加东西的问题是,当你执行 for(i in arr) {...} 时,该函数将显示为一个元素
                            • 但请记住,不建议扩展原生类型,因为它可能会干扰其他代码或未来的功能。
                            • 不要修改不属于你的对象
                            • 不要修改原型
                            【解决方案24】:

                            自定义数组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"
                            

                            演示: http://jsfiddle.net/UPphH/

                            【讨论】:

                            • 有没有一种紧凑的方法可以让这个版本在参数中找到一个数组时也合并一个数组?
                            • 我不明白第一个结果["b", "X", "Y", "Z", "c"]。为什么不包括"d"?在我看来,如果您将 6 作为 slice() 的第二个参数,并且数组中有 6 个元素从指定的索引开始,那么您应该在返回值中获得所有 6 个元素。 (文档为该参数说howMany。)developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
                            • 实际上,如果我使用 3 或更大的索引,我在输出中什么也得不到(案例 1.,FireFox)["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(3, 3); => [ ]
                            • @AlexisWilke 在第一个示例中,我使用了slice 方法,而不是您在评论中提到的spliceslice 的第二个参数(名为 end)是 结束提取的从零开始的索引。 slice 提取最多但不包括 end。因此在insert 之后有["a", "b", "X", "Y", "Z", "c", "d"]slice 从中提取索引从16 的元素,即从"b""d",但不包括"d"。有意义吗?
                            • 由于某种原因,当我使用 insert2 时,我得到一个“预期 1 个参数,但得到 2 个”异常。
                            猜你喜欢
                            • 2020-07-24
                            • 2021-07-08
                            • 1970-01-01
                            • 2017-02-11
                            • 1970-01-01
                            • 1970-01-01
                            • 2022-01-25
                            • 1970-01-01
                            相关资源
                            最近更新 更多