在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]); }
我偶然发现这个问题,试图理解如何从数组中删除每一个元素的出现。 这里有一个比较 splice
和delete
从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"]
从核心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
目前有两种方法可以做到这一点
-
使用拼接()
arrayObject.splice(index, 1);
-
使用删除
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'];