在 JavaScript 中删除数组元素 - 删除与拼接
使用和delete
有什么区别数组元素上的运算符,而不是使用 Array.splice
方法?
例如:
myArray = ['a', 'b', 'c', 'd'];
delete myArray[1];
// or
myArray.splice (1, 1);
如果我可以像删除对象一样删除数组元素,为什么还要使用 splice 方法呢?
What is the difference between using the delete
operator on the array element as opposed to using the Array.splice
method?
For example:
myArray = ['a', 'b', 'c', 'd'];
delete myArray[1];
// or
myArray.splice (1, 1);
Why even have the splice method if I can delete array elements like I can with objects?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(29)
delete
将删除对象属性,但不会重新索引数组或更新其长度。 这使得它看起来像是未定义的:请注意,它实际上并未设置为值
未定义
,而是该属性已从数组中删除,使其看起来未定义。 Chrome 开发工具通过在记录数组时打印empty
来明确这一区别。myArray.splice(start, deleteCount)
实际上删除了元素,重新索引了数组,并改变了它的长度。
delete
will delete the object property, but will not reindex the array or update its length. This makes it appears as if it is undefined:Note that it is not in fact set to the value
undefined
, rather the property is removed from the array, making it appear undefined. The Chrome dev tools make this distinction clear by printingempty
when logging the array.myArray.splice(start, deleteCount)
actually removes the element, reindexes the array, and changes its length.Array.remove() 方法
John Resig</strong>,jQuery 的创建者创建了一个非常方便的
Array.remove
方法,我总是在我的项目中使用它。以下是如何使用它的一些示例:
John 的网站
Array.remove() Method
John Resig, creator of jQuery created a very handy
Array.remove
method that I always use it in my projects.and here's some examples of how it could be used:
John's website
因为delete只是从数组元素中删除对象,所以数组的长度不会改变。 拼接删除对象并缩短数组。
下面的代码将显示“a”,“b”,“undefined”,“d”,
而这将显示“a”,“b”,“d”
Because delete only removes the object from the element in the array, the length of the array won't change. Splice removes the object and shortens the array.
The following code will display "a", "b", "undefined", "d"
Whereas this will display "a", "b", "d"
我在尝试了解如何从数组中删除元素的每个出现时偶然发现了这个问题。 这是
拼接
和删除
的比较从items
数组中删除每个'c'
。I stumbled onto this question while trying to understand how to remove every occurrence of an element from an Array. Here's a comparison of
splice
anddelete
for removing every'c'
from theitems
Array.来自 核心 JavaScript 1.5 参考 > 运算符> 特殊操作员> 删除运算符:
From Core JavaScript 1.5 Reference > Operators > Special Operators > delete Operator :
正如上面多次提到的,使用 splice() 似乎是一个完美的选择。 Mozilla 文档:
As stated many times above, using
splice()
seems like a perfect fit. Documentation at Mozilla:splice
将使用数字索引。而
delete
可用于其他类型的索引..示例:
splice
will work with numeric indices.whereas
delete
can be used against other kind of indices..example:
也许还值得一提的是,splice 仅适用于数组。 (不能依赖对象属性遵循一致的顺序。)
要从对象中删除键值对,delete 实际上就是您想要的:
It's probably also worth mentioning that splice only works on arrays. (Object properties can't be relied on to follow a consistent order.)
To remove the key-value pair from an object, delete is actually what you want:
删除与拼接
从数组中删除项目时
当你拼接时
在删除的情况下,元素被删除,但索引保持为空,
而在拼接的情况下,元素被删除并且其余元素的索引相应减少
delete Vs splice
when you delete an item from an array
when you splice
in case of delete the element is deleted but the index remains empty
while in case of splice element is deleted and the index of rest elements is reduced accordingly
通过记录应用
delete
运算符和splice()
方法后每个数组的长度可以看出差异。 例如:delete 运算符
delete
运算符从数组中删除该元素,但该元素的“占位符”仍然存在。oak
已被删除,但它仍然占用数组中的空间。 因此,数组的长度仍为 5。splice() 方法
splice()
方法完全删除了目标值和“占位符”。oak
及其在数组中占用的空间已被删除。 数组的长度现在为 4。The difference can be seen by logging the length of each array after the
delete
operator andsplice()
method are applied. For example:delete operator
The
delete
operator removes the element from the array, but the "placeholder" of the element still exists.oak
has been removed but it still takes space in the array. Because of this, the length of the array remains 5.splice() method
The
splice()
method completely removes the target value and the "placeholder" as well.oak
has been removed as well as the space it used to occupy in the array. The length of the array is now 4.删除就像一个非现实世界的情况,它只是删除该项目,但数组长度保持不变:
来自节点终端的示例:
这是一个删除项目的函数按索引创建数组,使用 slice(),它将 arr 作为第一个参数,将要删除的成员的索引作为第二个参数。 正如你所看到的,它实际上删除了数组的成员,并将数组长度减少 1
上面的函数所做的就是将索引之前的所有成员以及索引之后的所有成员连接在一起,并返回结果。
这是一个使用上面的函数作为节点模块的示例,查看终端将很有用:
请注意,这不适用于其中包含重复项的数组,因为indexOf(“c”)只会获得第一次出现,并且仅拼接并删除它找到的第一个“c”。
delete acts like a non real world situation, it just removes the item, but the array length stays the same:
example from node terminal:
Here is a function to remove an item of an array by index, using slice(), it takes the arr as the first arg, and the index of the member you want to delete as the second argument. As you can see, it actually deletes the member of the array, and will reduce the array length by 1
What the function above does is take all the members up to the index, and all the members after the index , and concatenates them together, and returns the result.
Here is an example using the function above as a node module, seeing the terminal will be useful:
please note that this will not work one array with dupes in it, because indexOf("c") will just get the first occurance, and only splice out and remove the first "c" it finds.
如果要迭代一个大数组并有选择地删除元素,则每次删除都调用 splice() 的成本会很高,因为 splice() 每次都必须重新索引后续元素。 因为数组在 Javascript 中是关联的,所以删除单个元素然后重新索引数组会更有效。
您可以通过构建一个新数组来做到这一点。 例如,
但我认为您不能修改原始数组中的键值,这会更有效 - 看起来您可能必须创建一个新数组。
请注意,您不需要检查“未定义”条目,因为它们实际上并不存在,并且 for 循环不会返回它们。 这是数组打印的产物,将它们显示为未定义。 它们似乎不存在于记忆中。
如果您可以使用像 slice() 这样的东西会更好,它会更快,但它不会重新索引。 有人知道更好的方法吗?
实际上,您可以按如下方式就地执行此操作,这可能更有效,性能更佳:
If you want to iterate a large array and selectively delete elements, it would be expensive to call splice() for every delete because splice() would have to re-index subsequent elements every time. Because arrays are associative in Javascript, it would be more efficient to delete the individual elements then re-index the array afterwards.
You can do it by building a new array. e.g
But I don't think you can modify the key values in the original array, which would be more efficient - it looks like you might have to create a new array.
Note that you don't need to check for the "undefined" entries as they don't actually exist and the for loop doesn't return them. It's an artifact of the array printing that displays them as undefined. They don't appear to exist in memory.
It would be nice if you could use something like slice() which would be quicker, but it does not re-index. Anyone know of a better way?
Actually, you can probably do it in place as follows which is probably more efficient, performance-wise:
你可以使用这样的东西
you can use something like this
性能
关于功能差异已经有很多很好的答案 - 所以这里我想重点关注性能。 今天(2020 年 6 月 25 日)我对 Chrome 83.0、Safari 13.1 和 Firefox 77.0 进行了测试,以获取有问题的解决方案以及所选答案
结论,
splice
(B) 解决方案对于小型和大型阵列delete
(A) 解决方案对于大型和中型阵列最快,对于小型阵列,filter
(E) 解决方案在 Chrome 和 Firefox 上对于小型阵列最快(但在 Safari 上最慢,对于大数组来说很慢)详细信息
我对解决方案执行以下测试
A
B
C
D
E (my)
Chrome 的示例结果
Performance
There are already many nice answer about functional differences - so here I want to focus on performance. Today (2020.06.25) I perform tests for Chrome 83.0, Safari 13.1 and Firefox 77.0 for solutions mention in question and additionally from chosen answers
Conclusions
splice
(B) solution is fast for small and big arraysdelete
(A) solution is fastest for big and medium fast for small arraysfilter
(E) solution is fastest on Chrome and Firefox for small arrays (but slowest on Safari, and slow for big arrays)Details
I perform following tests for solutions
A
B
C
D
E (my)
Example results for Chrome
为什么不直接过滤呢? 我认为这是在js中考虑数组最清晰的方式。
Why not just filter? I think it is the most clear way to consider the arrays in js.
它们是具有不同目的的不同事物。
splice
是特定于数组的,当用于删除时,会从数组中删除条目并向上移动所有先前的条目以填补空白。 (它也可用于插入条目,或同时插入两者。)splice
将更改数组的length
(假设它不是无操作调用:theArray.splice(x, 0)
)。delete
不是特定于数组的; 它设计用于对象:它从您使用它的对象中删除属性(键/值对)。 它仅适用于数组,因为 JavaScript 中的标准(例如非类型化)数组 根本不是真正的数组*,它们是对某些属性进行特殊处理的对象,例如那些名称为“数组索引”的对象(它们是定义为字符串名称“...其数值i
的范围为+0 ≤ i < 2^32-1
") 和length
。 当您使用delete
删除数组条目时,它所做的只是删除该条目; 它不会移动后面的其他条目来填补空白,因此数组变得“稀疏”(有些条目完全丢失)。 它对长度
没有影响。该问题的几个当前答案错误地指出使用
delete
“将条目设置为未定义
”。 这是不正确的。 它完全删除条目(属性),留下一个间隙。让我们用一些代码来说明差异:
* (这是我贫血的小博客上的一篇文章)
They're different things that have different purposes.
splice
is array-specific and, when used for deleting, removes entries from the array and moves all the previous entries up to fill the gap. (It can also be used to insert entries, or both at the same time.)splice
will change thelength
of the array (assuming it's not a no-op call:theArray.splice(x, 0)
).delete
is not array-specific; it's designed for use on objects: It removes a property (key/value pair) from the object you use it on. It only applies to arrays because standard (e.g., non-typed) arrays in JavaScript aren't really arrays at all*, they're objects with special handling for certain properties, such as those whose names are "array indexes" (which are defined as string names "...whose numeric valuei
is in the range+0 ≤ i < 2^32-1
") andlength
. When you usedelete
to remove an array entry, all it does is remove the entry; it doesn't move other entries following it up to fill the gap, and so the array becomes "sparse" (has some entries missing entirely). It has no effect onlength
.A couple of the current answers to this question incorrectly state that using
delete
"sets the entry toundefined
". That's not correct. It removes the entry (property) entirely, leaving a gap.Let's use some code to illustrate the differences:
* (that's a post on my anemic little blog)
其他人已经正确地将
delete
与splice
进行了比较。另一个有趣的比较是删除与未定义:删除的数组项比刚刚设置为未定义的数组项使用更少的内存;
例如,此代码将无法完成:
它会产生此错误:
因此,正如您所看到的
undefined
实际上占用了堆内存。但是,如果您还
删除
ary-item(而不是仅仅将其设置为未定义
),代码将慢慢完成:这些是极端的例子,但它们说明了一点关于
delete
,我没有看到任何人在任何地方提到过。Others have already properly compared
delete
withsplice
.Another interesting comparison is
delete
versusundefined
: a deleted array item uses less memory than one that is just set toundefined
;For example, this code will not finish:
It produces this error:
So, as you can see
undefined
actually takes up heap memory.However, if you also
delete
the ary-item (instead of just setting it toundefined
), the code will slowly finish:These are extreme examples, but they make a point about
delete
that I haven't seen anyone mention anywhere.我有两个方法。
简单的一个:
第二个:
第二个的优点是您可以删除一个值(全部,而不仅仅是像大多数一样的第一个实例)
I have two methods.
Simple one:
Second one:
The advantage to the second one is you can remove a value (all, not just first instance like most)
示例:
删除香蕉且数组长度 = 2
example:
banana is deleted and array length = 2
目前有两种方法
使用 splice()
arrayObject.splice(index, 1);
使用删除
delete arrayObject[index];
但我总是建议对数组对象使用 splice,对对象属性使用 delete因为删除不会更新数组长度。
Currently there are two ways to do this
using splice()
arrayObject.splice(index, 1);
using delete
delete arrayObject[index];
But I always suggest to use splice for array objects and delete for object attributes because delete does not update array length.
如果你有小数组,你可以使用
过滤器
:If you have small array you can use
filter
:好的,假设我们有下面这个数组:
让我们先删除:
这就是结果:
空!,让我们得到它:
所以意味着只删除了值,并且它是未定义现在,所以长度是相同的,它也会返回true...
让我们重置我们的数组并使用拼接来完成:
这就是这次的结果:
正如你所看到的数组长度改变了并且
arr[1]
现在是 3...此外,这还将返回数组中已删除的项目,在本例中为
[3]
...OK, imagine we have this array below:
Let's do delete first:
and this is the result:
empty! and let's get it:
So means just the value deleted and it's undefined now, so length is the same, also it will return true...
Let's reset our array and do it with splice this time:
and this is the result this time:
As you see the array length changed and
arr[1]
is 3 now...Also this will return the deleted item in an Array which is
[3]
in this case...保持简单:-
当您删除数组中的任何元素时,它将删除提到的位置的值并使其为空/未定义,但该位置存在于数组中。
其中在 splice 原型中,参数如下。 //arr.splice(开始删除的位置,删除的项目数)
Keep it simple :-
When you delete any element in an array, it will delete the value of the position mentioned and makes it empty/undefined but the position exist in the array.
where as in splice prototype the arguments are as follows. //arr.splice(position to start the delete , no. of items to delete)
最简单的方法可能是
希望这有帮助。
参考:https://lodash.com/docs#compact
Easiest way is probably
Hope this helps.
Reference: https://lodash.com/docs#compact
对于那些想要使用 Lodash 的人可以使用:
myArray = _.without(myArray, itemToRemove)
或者像我在 Angular2 中使用的那样
For those who wants to use Lodash can use:
myArray = _.without(myArray, itemToRemove)
Or as I use in Angular2
从最后删除元素
从第一个删除元素 从
中间删除
从最后删除一个元素
使用数组索引号删除
Delete element from last
Delete element from first
Delete from middle
Delete one element from last
Delete by using array index number
如果要删除的元素位于中间(假设我们要删除索引为 1 的“c”),则可以使用:
If the desired element to delete is in the middle (say we want to delete 'c', which its index is 1), you can use:
IndexOf
还接受引用类型。 假设以下场景:不同的是:
IndexOf
accepts also a reference type. Suppose the following scenario:Differently:
// 结果 : myArray = ['b', 'c', 'd'];
// result : myArray = ['b', 'c', 'd'];