首页 文章

在JavaScript中删除数组元素 - 删除vs splice

提问于
浏览
1226

在数组元素上使用the delete operator与使用the Array.splice method相比有什么区别?

例如:

myArray = ['a', 'b', 'c', 'd'];

delete myArray[1];
//  or
myArray.splice (1, 1);

如果我能用对象删除数组元素,为什么甚至有拼接方法呢?

23 回答

  • 5

    来自Core JavaScript 1.5 Reference > Operators > Special Operators > delete Operator

    删除数组元素时,数组长度不受影响 . 例如,如果删除[3],则[4]仍为[4]且[3]未定义 . 即使删除数组的最后一个元素(删除[a.length-1]),这也成立 .

  • 0

    delete Vs splice

    从数组中删除项目时

    var arr = [1,2,3,4]; delete arr[2]; console.log(arr)
    //result
    [1, 2, 3:, 4]
    

    当你拼接

    var arr = [1,2,3,4]; arr.splice(1,1); console.log(arr)
    //result
     [1, 3, 4]
    

    如果 delete element is deleted 但是 index remains empty

    而在 splice 元素被删除的情况下 index of rest elements is reduced accordingly

  • 2
    function remove_array_value(array, value) {
        var index = array.indexOf(value);
        if (index >= 0) {
            array.splice(index, 1);
            reindex_array(array);
        }
    }
    function reindex_array(array) {
       var result = [];
        for (var key in array) {
            result.push(array[key]);
        }
        return result;
    }
    

    例:

    var example_arr = ['apple', 'banana', 'lemon'];   // length = 3
    remove_array_value(example_arr, 'banana');
    

    banana被删除,数组长度= 2

  • 2

    最简单的方法可能就是

    var myArray = ['a', 'b', 'c', 'd'];
    delete myArray[1]; // ['a', undefined, 'c', 'd']. Then use lodash compact method to remove false, null, 0, "", undefined and NaN
    myArray = _.compact(myArray); ['a', 'c', 'd'];
    

    希望这可以帮助 . 参考:https://lodash.com/docs#compact

  • 8

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

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

    我们先删除:

    delete arr[1];
    

    这就是结果:

    [1, empty, 3, 4, 5];
    

    empty! 让我们明白:

    arr[1]; //undefined
    

    所以意味着只删除了值,它现在是 undefined ,所以长度是相同的,它也将返回 true ...

    让我们重置我们的数组,这次拼接:

    arr.splice(1, 1);
    

    这次是结果:

    [1, 3, 4, 5];
    

    如您所见,数组长度已更改, arr[1] 现在为 3 ...

    此外,这将返回数组中已删除的项目,在这种情况下 [3] ...

  • 0

    你可以使用这样的东西

    var my_array = [1,2,3,4,5,6];
    delete my_array[4];
    console.log(my_array.filter(function(a){return typeof a !== 'undefined';}));
    

    应该显示[1,2,3,4,6]

  • 7

    如果你想迭代一个大数组并有选择地删除元素,那么为每次删除调用splice()都会很昂贵,因为splice()每次都必须重新索引后续元素 . 因为数组在Javascript中是关联的,所以删除单个元素然后重新索引数组会更有效 .

    您可以通过构建新数组来实现 . 例如

    function reindexArray( array )
    {
           var result = [];
            for( var key in array )
                    result.push( array[key] );
            return result;
    };
    

    但我认为您不能修改原始数组中的键值,这样会更有效 - 看起来您可能需要创建一个新数组 .

    请注意,您不需要检查“未定义”条目,因为它们实际上并不存在,并且for循环不会返回它们 . 它是阵列打印的工件,将它们显示为未定义 . 它们似乎不存在于内存中 .

    如果你可以使用像slice()这样的东西会更快,但它不会重新索引会很好 . 谁知道更好的方法?


    实际上,您可以按照以下方式执行此操作,这可能更有效,性能更高:

    reindexArray : function( array )
    {
        var index = 0;                          // The index where the element should be
        for( var key in array )                 // Iterate the array
        {
            if( parseInt( key ) !== index )     // If the element is out of sequence
            {
                array[index] = array[key];      // Move it to the correct, earlier position in the array
                ++index;                        // Update the index
            }
        }
    
        array.splice( index );  // Remove any remaining elements (These will be duplicates of earlier items)
    },
    
  • 2

    如果要删除的所需元素位于中间(假设我们要删除'c',其索引为1):

    var arr = ['a','b','c'];

    你可以使用: var indexToDelete = 1; var newArray = arr.slice(0, indexToDelete).combine(arr.slice(indexToDelete+1, arr.length))

  • 0

    值得一提的是,splice只适用于数组 . (不能依赖对象属性来遵循一致的顺序 . )

    要从对象中删除键值对,删除实际上是您想要的:

    delete myObj.propName;     // , or:
    delete myObj["propName"];  // Equivalent.
    
  • 5

    我偶然发现了这个问题,同时试图了解如何从Array中删除每个元素 . Here's a comparisonsplicedelete 用于从 items 数组中删除每个 'c' .

    var items = ['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'];
    
    while (items.indexOf('c') !== -1) {
      items.splice(items.indexOf('c'), 1);
    }
    
    console.log(items); // ["a", "b", "d", "a", "b", "d"]
    
    items = ['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'];
    
    while (items.indexOf('c') !== -1) {
      delete items[items.indexOf('c')];
    }
    
    console.log(items); // ["a", "b", undefined, "d", "a", "b", undefined, "d"]
    ​
    
  • 0

    如上所述,使用 splice() 似乎是完美的选择 . Documentation at Mozilla:

    splice()方法通过删除现有元素和/或添加新元素来更改数组的内容 . var myFish = ['天使','小丑','普通话','鲟鱼'];

    myFish.splice(2,0,'鼓');
    // myFish是[“天使”,“小丑”,“鼓”,“普通话”,“鲟鱼”]

    myFish.splice(2,1);
    // myFish是[“天使”,“小丑”,“普通话”,“鲟鱼”]
    语法array.splice(start)
    array.splice(start,deleteCount)
    array.splice(start,deleteCount,item1,item2,...)
    参数start要开始更改数组的索引 . 如果大于数组的长度,实际的起始索引将设置为数组的长度 . 如果否定,将从最后开始那么多元素 . deleteCount一个整数,指示要删除的旧数组元素的数量 . 如果deleteCount为0,则不删除任何元素 . 在这种情况下,您应该至少指定一个新元素 . 如果deleteCount大于从start开始的数组中剩余的元素数,则将删除通过数组末尾的所有元素 . 如果省略deleteCount,则deleteCount将等于(arr.length - start) . item1,item2,...从开始索引开始添加到数组的元素 . 如果未指定任何元素,则splice()将仅从数组中删除元素 . 返回值包含已删除元素的数组 . 如果仅删除一个元素,则返回一个元素的数组 . 如果未删除任何元素,则返回空数组 . [...]

  • 2

    它们是具有不同目的的不同事物 .

    splice 是特定于阵列的,当用于删除时,从数组中删除条目并移动所有先前的条目条目填补空白 . (它也可以用于同时插入条目或两者 . ) splice 将更改数组的 length (假设它不是无操作调用: theArray.splice(x, 0) ) .

    delete 不是特定于数组的;它设计用于对象:它从您使用它的对象中删除属性(键/值对) . 它仅适用于数组,因为JavaScript aren't really arrays at all *中的标准(例如,非类型)数组,它们是对某些属性具有特殊处理的对象,例如名称为"array indexes"的那些(其为defined作为字符串名称“......数值 i+0 ≤ i < 2^32-1 “)和 length 范围内 . 当您使用 delete 删除数组条目时,它只是删除条目;它不会移动其他条目以填补空白,因此数组变为"sparse"(完全缺少某些条目) . 它对 length 没有影响 .

    这个问题的当前几个答案错误地指出使用 delete “将条目设置为 undefined ” . 那不对 . 它完全删除了条目(属性),留下了空白 .

    让我们用一些代码来说明差异:

    console.log("Using `splice`:");
    var a = ["a", "b", "c", "d", "e"];
    console.log(a.length);            // 5
    a.splice(0, 1);
    console.log(a.length);            // 4
    console.log(a[0]);                // "b"
    
    console.log("Using `delete`");
    var a = ["a", "b", "c", "d", "e"];
    console.log(a.length);            // 5
    delete a[0];
    console.log(a.length);            // still 5
    console.log(a[0]);                // undefined
    console.log("0" in a);            // false
    console.log(a.hasOwnProperty(0)); // false
    
    console.log("Setting to `undefined`");
    var a = ["a", "b", "c", "d", "e"];
    console.log(a.length);            // 5
    a[0] = undefined;
    console.log(a.length);            // still 5
    console.log(a[0]);                // undefined
    console.log("0" in a);            // true
    console.log(a.hasOwnProperty(0)); // true
    

    *(这是我贫血的小博客上的帖子)

  • 9

    IndexOf 也接受引用类型 . 假设以下场景:

    var arr = [{item: 1}, {item: 2}, {item: 3}];
    
    var found = find(2, 3); //pseudo code: will return [{item: 2}, {item:3}]
    
    var l = found.length;
    while(l--) {
      var index = arr.indexOf(found[l])
      arr.splice(index, 1);
    }
    
    console.log(arr.length); //1
    

    以不同的方式:

    var item2 = findUnique(2); //will return {item: 2}
    var l = arr.length;
    var found = false;
      while(!found && l--) {
      found = arr[l] === item2;
    }
    
    console.log(l, arr[l]);// l is index, arr[l] is the item you look for
    
  • 99
    function deleteFromArray(array, indexToDelete){
      var remain = new Array();
      for(var i in array){
        if(array[i] == indexToDelete){
          continue;
        }
        remain.push(array[i]);
      }
      return remain;
    }
    
    myArray = ['a', 'b', 'c', 'd'];
    deleteFromArray(myArray , 0);
    

    //结果:myArray = ['b','c','d'];

  • 1592

    delete 将删除对象属性,但不会重新索引数组或更新其长度 . 这使它看起来好像是未定义的:

    > myArray = ['a', 'b', 'c', 'd']
      ["a", "b", "c", "d"]
    > delete myArray[0]
      true
    > myArray[0]
      undefined
    

    请注意,它实际上未设置为值 undefined ,而是从数组中删除属性,使其显示为未定义 . Chrome开发工具通过在记录数组时打印 empty 来明确区分 .

    > myArray[0]
      undefined
    > myArray
      [empty, "b", "c", "d"]
    

    myArray.splice(start, deleteCount)实际上删除了元素,重新索引数组,并更改其长度 .

    > myArray = ['a', 'b', 'c', 'd']
      ["a", "b", "c", "d"]
    > myArray.splice(0, 2)
      ["a", "b"]
    > myArray
      ["c", "d"]
    
  • 7

    Array.remove()方法

    John Resig ,jQuery的创建者创建了一个非常方便的 Array.remove 方法,我总是在我的项目中使用它 .

    // Array Remove - By John Resig (MIT Licensed)
    Array.prototype.remove = function(from, to) {
      var rest = this.slice((to || from) + 1 || this.length);
      this.length = from < 0 ? this.length + from : from;
      return this.push.apply(this, rest);
    };
    

    以下是一些如何使用它的例子:

    // Remove the second item from the array
    array.remove(1);
    // Remove the second-to-last item from the array
    array.remove(-2);
    // Remove the second and third items from the array
    array.remove(1,2);
    // Remove the last and second-to-last items from the array
    array.remove(-2,-1);
    

    John's website

  • 1

    splice 将使用数字索引 .

    delete 可用于对抗其他类型的指数 .

    例:

    delete myArray['text1'];
    
  • 63

    因为delete仅从数组中的元素中删除对象,所以数组的长度不会更改 . Splice删除对象并缩短数组 .

    以下代码将显示“a”,“b”,“undefined”,“d”

    myArray = ['a', 'b', 'c', 'd']; delete myArray[2];
    
    for (var count = 0; count < myArray.length; count++) {
        alert(myArray[count]);
    }
    

    而这将显示“a”,“b”,“d”

    myArray = ['a', 'b', 'c', 'd']; myArray.splice(2,1);
    
    for (var count = 0; count < myArray.length; count++) {
        alert(myArray[count]);
    }
    
  • 0

    对于那些想要使用Lodash的人可以使用: myArray = _.without(myArray, itemToRemove)

    或者我在Angular2中使用

    import { without } from 'lodash';
    ...
    myArray = without(myArray, itemToRemove);
    ...
    
  • 14

    delete 就像一个非现实世界的情况,它只是删除了项目,但数组长度保持不变:

    来自节点终端的示例:

    > var arr = ["a","b","c","d"];
    > delete arr[2]
    true
    > arr
    [ 'a', 'b', , 'd', 'e' ]
    

    这是一个通过索引删除数组项的函数,使用 slice() ,它将arr作为第一个arg,并将要删除的成员的索引作为第二个参数 . 如您所见,它实际上删除了数组的成员,并将数组长度减少1

    function(arr,arrIndex){
        return arr.slice(0,arrIndex).concat(arr.slice(arrIndex + 1));
    }
    

    上面的函数是将所有成员带到索引,以及索引之后的所有成员,并将它们连接在一起,然后返回结果 .

    这是一个使用上面的函数作为节点模块的示例,看到终端将是有用的:

    > var arr = ["a","b","c","d"]
    > arr
    [ 'a', 'b', 'c', 'd' ]
    > arr.length
    4 
    > var arrayRemoveIndex = require("./lib/array_remove_index");
    > var newArray = arrayRemoveIndex(arr,arr.indexOf('c'))
    > newArray
    [ 'a', 'b', 'd' ] // c ya later
    > newArray.length
    3
    

    请注意,这对于一个带有dupes的数组不起作用,因为indexOf(“c”)只会获得第一次出现,并且只能拼接并删除它找到的第一个“c” .

  • 327

    为什么不过滤?我认为这是在js中考虑数组的最明确的方法 .

    myArray = myArray.filter(function(item){
        return item.anProperty != whoShouldBeDeleted
    });
    
  • 10

    目前有两种方法可以做到这一点

    • 使用splice()

    arrayObject.splice(index, 1);

    • 使用删除

    delete arrayObject[index];

    但我总是建议对数组对象使用splice并删除对象属性,因为delete不会更新数组长度 .

  • -1

    delete:delete将删除对象属性,但不会重新索引数组或更新其长度 . 这使得它看起来好像是未定义的:splice:实际上删除元素,重新索引数组,并更改其长度 .

    从最后删除元素

    arrName.pop();
    

    从第一个删除元素

    arrName.shift();
    

    从中间删除

    arrName.splice(starting index,number of element you wnt to delete);
    
    Ex: arrName.splice(1,1);
    

    从最后删除一个元素

    arrName.splice(-1);
    

    使用数组索引号删除

    delete arrName[1];
    

相关问题