在 JavaScript 中删除数组元素 - 删除与拼接
-
20-08-2019 - |
题
使用有什么区别 这 delete
操作员 在数组元素上而不是使用 这 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[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"]
其他提示
Array.remove()方法
约翰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);
由于仅删除删除该数组元素中的对象,该阵列的长度不会改变。剪接移除对象,缩短阵列。
下面的代码会显示 “A”, “B”, “未定义”, “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
的用于从'c'
阵列除去每items
。
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],A [4]是 仍然是[4]和[3]是未定义的。这个 即使你删除最后一个持有 该阵列的元件(删除 一个[则为a.length-1])。
splice
将与数字索引工作。
,而delete
可以针对其他类型的索引的使用..
示例:
delete myArray['text1'];
这可能也是值得一提的是,剪接仅适用于数组。 (对象属性不能依靠遵循一致的顺序。)
要删除对象的键值对,删除实际上是你想要什么:
delete myObj.propName; // , or:
delete myObj["propName"]; // Equivalent.
如所陈述的上述许多倍,采用splice()
似乎是一个完美的结合。 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,没有元素被删除。在这种情况下,你应该至少指定一个新元素。如果deleteCount高于剩余数组中元素的数目大起始于开始,那么所有的元素通过阵列的端部将被删除。
如果省略deleteCount,deleteCount将等于
(arr.length - start).
ITEM1,ITEM2,...
元素添加到阵列中,起始索引在开始。如果没有指定的任何元件,
splice()
只会移除从数组元素。返回值
包含删除的元素的数组。如果只有一个元素被删除,则返回一个元件的阵列。如果没有元件被移除,空数组被返回。
[...]
删除Vs的剪接强>
当你从数组中删除项目
var arr = [1,2,3,4]; delete arr[2]; //result [1, 2, 3:, 4]
console.log(arr)
在拼接
var arr = [1,2,3,4]; arr.splice(1,1); //result [1, 3, 4]
console.log(arr);
在的情况下的删除强>的元素被删除强>但在指数保持空强>
而在情况下的剪接强>元素被删除,并且其余元件的的指数相应降低强>
删除强>的作用就像一个非现实世界的情况,它只是移除的项目,但在阵列长度保持相同:
例如,从节点终端:
> var arr = ["a","b","c","d"];
> delete arr[2]
true
> arr
[ 'a', 'b', , 'd', 'e' ]
下面是一个函数来通过索引,取出数组的项使用的切片()下,它需要的ARR作为第一个参数,和该构件的索引要删除的第二个参数。正如可以看到的,它实际上删除阵列的构件,并且将减少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
请注意,这是行不通的一个阵列,以在它愚弄,因为的indexOf(“C”)将刚刚得到的第一次出现,只有拼接并删除第一个“C”找到。
如果要遍历大阵列和选择性地删除元素,这将是昂贵的调用剪接()为每个删除因为剪接()将必须每次重新索引后续元素。因为阵列在Javascript是关联的,这将是更有效地删除各个元件然后重新索引阵列之后。
您可以通过建立一个新的数组做到这一点。 e.g
function reindexArray( array )
{
var result = [];
for( var key in array )
result.push( array[key] );
return result;
};
但我不认为你可以在原数组,这将是更有效地在修改键值 - 它看起来你可能需要创建一个新的阵列
请注意,你不需要检查“未定义”项目,因为它们不实际存在和for循环不归还。这显示它们为未定义的阵列打印的神器。它们不会出现在内存中存在。
这将是很好,如果你可以使用类似切片(),它会更快,但它不会重新索引。任何人都知道一个更好的方式?
其实,如下这可能是更有效的你也许可以做到这一点的地方,性能方面:
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]
为什么不直接过滤?我认为这是考虑阵列中JS最明确的方式。
myArray = myArray.filter(function(item){
return item.anProperty != whoShouldBeDeleted
});
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
它们是具有不同目的的不同事物。
splice
是特定于数组的,当用于删除时,从数组中删除条目 和 将所有先前的条目向上移动以填补空白。(它也可用于插入条目,或同时插入两者。) splice
将改变 length
数组的(假设它不是无操作调用: theArray.splice(x, 0)
).
delete
不是特定于数组的;它设计用于以下物体:它从您使用它的对象中删除属性(键/值对)。它仅适用于数组,因为 JavaScript 中的标准(例如非类型)数组 根本不是真正的数组*,它们是对某些属性进行特殊处理的对象,例如那些名称为“数组索引”的对象(它们是 定义的 作为字符串名称“...其数值 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"
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
* (这是我贫血的小博客上的一篇文章)
目前有两种方法可以做到这一点
使用 splice()
arrayObject.splice(index, 1);
使用删除
delete arrayObject[index];
但我总是建议对数组对象使用 splice,对对象属性使用删除,因为删除不会更新数组长度。
的差异可以通过在施加delete
操作者和splice()
方法之后登录每个阵列的长度可以看出。例如:
删除操作者
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
delete trees[3];
console.log(trees); // ["redwood", "bay", "cedar", empty, "maple"]
console.log(trees.length); // 5
在delete
操作员删除该数组的元素,但该元素的“占位符”仍然存在。 oak
已被删除,但它仍然需要空间在数组中。正因为如此,在阵列的长度保持5。
splice()方法
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
trees.splice(3,1);
console.log(trees); // ["redwood", "bay", "cedar", "maple"]
console.log(trees.length); // 4
在splice()
方法完全消除目标值和强>的“占位符”为好。 oak
已被移除,以及使用它的阵列中占据的空间。所述阵列的长度现在为4。
行,假设我们具有低于该数组:
const arr = [1, 2, 3, 4, 5];
让我们先做删除:
delete arr[1];
和这是结果:
[1, empty, 3, 4, 5];
空并让我们得到它!
arr[1]; //undefined
所以意味着刚刚删除的价值和它的未定义现在,这样的长度是一样的,也将返回真正 ...
让我们重新排列,并与拼接做这种时间:
arr.splice(1, 1);
和这是结果这段时间:
[1, 3, 4, 5];
正如所看到的阵列长度改变,并且arr[1]
是<强> 3 立即...
此外,这将在其中在此情况下[3]
数组返回已删除的项目...
最简单的方法可能是
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
对于那些谁想要使用 Lodash 可以使用:
myArray = _.without(myArray, itemToRemove)
或者如我在Angular2使用
import { without } from 'lodash';
...
myArray = without(myArray, itemToRemove);
...
删除强>:删除将删除对象属性,但不会重新索引 阵列或更新它的长度。这使得它看起来好像是 未定义:
<强>剪接强>:实际上移除元件,重新索引的阵列,且变化 它的长度。
这最后删除元素
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];
如果要删除的所需的元件是在中间(比方说我们想删除“C”,其中它的索引为1),可以使用:
var arr = ['a','b','c'];
var indexToDelete = 1;
var newArray = arr.slice(0,indexToDelete).combine(arr.slice(indexToDelete+1, arr.length))
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
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'];