在JavaScript中删除数组元素 – 删除与拼接

在数组元素上使用delete操作符与使用Array.splice方法相比有什么Array.splice

例如:

 myArray = ['a', 'b', 'c', 'd']; delete myArray[1]; // or myArray.splice (1, 1); 

为什么即使有splice方法,如果我可以删除像我可以用对象数组元素?

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

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

Splice(start, deleteCount)实际上从数组中删除元素:

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

Array.remove()方法

jQuery创build者John Resig创build了一个非常方便的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); 

约翰的网站

因为删除只能从数组中的元素中删除对象,所以数组的长度不会改变。 拼接移除对象并缩短数组。

以下代码将显示“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]); } 

我偶然发现这个问题,试图理解如何从数组中删除每一个元素的出现。 这里有一个比较 splicedeleteitems数组中删除每个'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"]​ 

从核心JavaScript 1.5参考>运算符>特殊运算符>删除运算符 :

删除数组元素时,数组长度不受影响。 例如,如果您删除了[3],则[4]仍然是[4],并且[3]未定义。 即使删除数组的最后一个元素(删除[a.length-1]),也是如此。

splice将使用数字索引。

delete可以用来对付其他types的索引。

例:

 delete myArray['text1']; 

也许值得一提的是拼接只适用于数组。 (对象属性不能依赖于一致的顺序。)

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

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

删除Vs拼接

当你从数组中删除一个项目

 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] 

删除的情况下元素被删除,索引保持空白

而在拼接元素被删除的情况下, 其他元素索引也相应减less

如上所述,使用splice()似乎是一个完美的select。 Mozilla文档:

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

 var myFish = ['angel', 'clown', 'mandarin', 'sturgeon']; myFish.splice(2, 0, 'drum'); // myFish is ["angel", "clown", "drum", "mandarin", "sturgeon"] myFish.splice(2, 1); // myFish is ["angel", "clown", "mandarin", "sturgeon"] 

句法

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

参数

开始

开始更改数组的索引。 如果大于数组的长度,实际的起始索引将被设置为数组的长度。 如果否定的话,会从最后开始那么多元素。

deleteCount

一个整数,指示要删除的旧数组元素的数量。 如果deleteCount为0,则不会删除任何元素。 在这种情况下,您应该至less指定一个新元素。 如果deleteCount大于数组中剩余的元素的数量,那么数组尾部的所有元素都将被删除。

如果省略deleteCount,则deleteCount将等于(arr.length - start).

item1,item2,…

从开始索引处开始添加到数组的元素。 如果不指定任何元素, splice()将只从数组中移除元素。

返回值

包含已删除元素的数组。 如果只有一个元素被删除,则返回一个元素的数组。 如果没有元素被删除,则返回一个空数组。

[…]

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

来自节点terminal的例子:

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

这是一个函数,通过索引来删除一个数组的项目,使用slice() ,它将arr作为第一个参数,并将要删除的成员的索引作为第二个参数。 正如你所看到的,它实际上删除了数组的成员,并将数组长度减1

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

上面所做的function是把所有成员都带到索引中,然后把索引后的所有成员连接在一起,并返回结果。

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

 > 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 

请注意,这将不会在一个数组中使用dupe,因为indexOf(“c”)只会得到第一个出现,并且只拼接并删除它find的第一个“c”。

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

你可以通过build立一个新的数组来完成。 例如

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

但我不认为你可以修改原始数组中的键值,这将更有效 – 看起来你可能不得不创build一个新的数组。

请注意,您不需要检查“未定义”条目,因为它们实际上不存在,并且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) }, 

你可以使用这样的东西

 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]

 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'); 

香蕉被删除,数组长度= 2

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

  1. 使用拼接()

    arrayObject.splice(index, 1);

  2. 使用删除

    delete arrayObject[index];

但我总是build议使用数组对象的拼接,并删除对象的属性,因为删除不更新数组的长度。

他们是不同的东西,有不同的目的。

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

delete不是arrays特定的; 它被devise用于对象:它从你使用它的对象中删除一个属性(键/值对)。 它只适用于数组,因为JavaScript 中的标准(如非types)数组根本不是真正的数组 *,它们是对特定属性(如名称为“数组索引” 定义为string名称“…其数值i在范围+0 ≤ i < 2^32-1 ”)和length 。 当你使用delete删除一个数组条目时,它所做的就是删除条目; 它不会移动其他条目来填补空白,所以数组变得“稀疏”(有一些条目完全丢失)。 它对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" 

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

或者当我在Angular2中使用

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

IndexOf也接受一个引用types。 假设以下情况:

 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 

如果想要删除的元素在中间(比如我们想删除'c',它的索引是1):

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

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

最简单的方法可能是

 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

为什么不过滤? 我认为这是考虑js中数组的最清晰的方法。

 myArray = myArray.filter(function(item){ return item.anProperty != whoShouldBeDeleted }); 
 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'];