Array.prototype.destroy = function(obj){
// Return null if no objects were found and removed
var destroyed = null;
for(var i = 0; i < this.length; i++){
// Use while-loop to find adjacent equal objects
while(this[i] === obj){
// Remove this[i] and store it within destroyed
destroyed = this.splice(i, 1)[0];
}
}
return destroyed;
}
//Set-up some dummy data
var dummyObj = {name:"meow"};
var dummyArray = [dummyObj, "item1", "item1", "item2"];
//Remove the dummy data
removeFromArray(dummyArray, dummyObj);
removeFromArray(dummyArray, "item2");
输出 - 正如所料 . [“item1”,“item1”]
您可能有不同的需求,因此您可以轻松修改它以适应它们 . 我希望这可以帮助别人 .
14
无需使用 indexOf 或 splice . 但是,如果您只想删除一个元素,它会表现得更好 .
Find and move (move):
function move(arr, val) {
var j = 0;
for (var i = 0, l = arr.length; i < l; i++) {
if (arr[i] !== val) {
arr[j++] = arr[i];
}
}
arr.length = j;
}
Use indexOf and splice (indexof):
function indexof(arr, val) {
var i;
while ((i = arr.indexOf(val)) != -1) {
arr.splice(i, 1);
}
}
Use only splice (splice):
function splice(arr, val) {
for (var i = arr.length; i--;) {
if (arr[i] === val) {
arr.splice(i, 1);
}
}
}
Run-times on nodejs for array with 1000 elements (average over 10000 runs):
var removed = helper.removeOne(arr, row => row.id === 5 );
var removed = helper.remove(arr, row => row.name.startsWith('BMW'));
定义
var helper = {
// Remove and return the first occurrence
removeOne: function(array, predicate) {
for (var i = 0; i < array.length; i++) {
if (predicate(array[i])) {
return array.splice(i, 1);
}
}
},
// Remove and return all occurrences
remove: function(array, predicate) {
var removed = [];
for (var i = 0; i < array.length;) {
if (predicate(array[i])) {
removed.push(array.splice(i, 1));
continue;
}
i++;
}
return removed;
}
};
32
Array.prototype.remByVal = function(val) {
for (var i = 0; i < this.length; i++) {
if (this[i] === val) {
this.splice(i, 1);
i--;
}
}
return this;
}
//Call like
[1, 2, 3, 4].remByVal(3);
Array.prototype.remByVal = function(val) {
for (var i = 0; i < this.length; i++) {
if (this[i] === val) {
this.splice(i, 1);
i--;
}
}
return this;
}
var rooms = ['hello', 'something']
rooms = rooms.remByVal('hello')
console.log(rooms)
Array.prototype.indexOf || (Array.prototype.indexOf = function(d, e) {
var a;
if (null == this) throw new TypeError('"this" is null or not defined');
var c = Object(this),
b = c.length >>> 0;
if (0 === b) return -1;
a = +e || 0;
Infinity === Math.abs(a) && (a = 0);
if (a >= b) return -1;
for (a = Math.max(0 <= a ? a : b - Math.abs(a), 0); a < b;) {
if (a in c && c[a] === d) return a;
a++
}
return -1
});
30 回答
看看这段代码 . 它适用于每一个 major browser .
调用此功能
如果要删除已删除位置的新数组,可以始终删除特定元素并过滤掉数组 . 对于没有实现过滤方法的浏览器,它可能需要array object的扩展,但从长远来看,它更容易,因为你所做的只是:
应显示
[1, 2, 3, 4, 6]
你永远不应该在你的数组中改变你的数组 . 因为这是针对功能编程模式的 . 您可以做的是创建一个新数组,而不引用要使用es6方法更改数据的数组
filter
;假设您要从数组中删除
5
,您可以像这样简单地执行此操作 .这将为您提供一个没有您想要删除的值的新数组 . 结果将是
为了进一步了解,您可以阅读有关Array.filter https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter的MDN文档 .
Update: 仅当您不能使用ECMAScript 2015(以前称为ES6)时,才推荐使用此方法 . 如果你可以使用它,这里的其他答案提供了更简洁的实现 .
This gist here将解决您的问题,并且还会删除所有出现的参数,而不是仅删除1(或指定的值) .
用法:
OK, 例如,你有以下数组:
我们想删除4号,你可以简单地做下面的代码:
如果重新使用此函数,则编写一个可重用的函数,该函数将附加到Native数组函数,如下所示:
但是,如果您使用下面的数组而不是数组中的[5] s,那怎么样?
我们需要一个循环来检查所有这些,但更简单,更有效的方法是使用内置的JavaScript函数,所以我们编写一个使用过滤器的函数,如下所示:
还有第三方库可以帮助你做这些,比如Lodash或Underscore,有关更多信息,请查看lodash .pull,.pullAt或_.without .
我是JavaScript的新手,需要这个功能 . 我只写了这个:
然后,当我想使用它时:
输出 - 正如所料 . [“item1”,“item1”]
您可能有不同的需求,因此您可以轻松修改它以适应它们 . 我希望这可以帮助别人 .
无需使用
indexOf
或splice
. 但是,如果您只想删除一个元素,它会表现得更好 .Find and move (move):
Use indexOf and splice (indexof):
Use only splice (splice):
Run-times on nodejs for array with 1000 elements (average over 10000 runs):
indexof比移动慢大约10倍 . 即使通过在splice中删除对
indexOf
的调用来改进它,它也比移动更糟糕 .你有1到9个数组,你想删除5使用下面的代码 .
如果你想要多个值ex: - 1,7,8
如果要删除数组ex中的数组值: - [3,4,5]
包含支持的浏览器是link
以下是 remove an item from an array using JavaScript 的几种方法 .
所有方法都描述为 do not mutate the original array ,而是创建一个新方法 .
如果您知道项目的索引
假设您有一个数组,并且想要删除
i
位置的项目 .一种方法是使用
slice()
:slice()
使用它接收的索引创建一个新数组 . 我们只是创建一个新数组,从开始到我们想要删除的索引,并从我们删除的数据到数组末尾之后的第一个位置连接另一个数组 .如果你知道 Value
在这种情况下,一个好的选择是使用
filter()
,它提供了更具说明性的方法:这使用ES6箭头功能 . 您可以使用传统功能来支持旧版浏览器:
或者您可以使用Babel并将ES6代码转发回ES5,使其更易于浏览旧浏览器,同时在代码中编写现代JavaScript .
删除多个项目
如果不是单个项目,您想要删除多个项目,该怎么办?
让我们找到最简单的解决方案 .
按索引
您只需创建一个函数并删除系列中的项目:
按 Value 计算
您可以在回调函数中搜索包含:
避免改变原始数组
splice()
(不要与slice()
混淆)改变原始数组,应该避免 .(最初发布于https://flaviocopes.com/how-to-remove-item-from-array/)
太老了回复,但可能通过提供谓词而不是值来帮助某人 .
NOTE: 它将更新给定的数组,并返回受影响的行
用法
定义
您可以使用filter方法轻松完成:
这将从数组中删除所有元素,并且比slice和indexOf的组合更快地工作
您可以使用ES6 .
输出:
如果阵列中有复杂对象,可以使用过滤器吗?在$ .inArray或array.splice不那么容易使用的情况下 . 特别是如果对象在数组中可能很浅 .
例如 . 如果您有一个带有Id字段的对象,并且您希望从数组中删除该对象:
我不知道你是如何期待
array.remove(int)
表现的 . 我可以想到你可能想要的三种可能性 .删除数组中的元素index
i
:如果要从数组中删除值为
number
的每个元素:如果您只想使索引
i
处的元素不再存在,但您不希望其他元素的索引发生更改:你可以使用lodash _.pull(变异数组),_.pullAt(变异数组)或_.without(不变异数组),
John Resig posted a good implementation:
如果您不想扩展全局对象,则可以执行以下操作:
但我发布这个的主要原因是警告用户不要使用该页面评论中建议的替代实现(2007年12月14日):
它起初似乎运行良好,但是通过一个痛苦的过程,我发现它在尝试删除数组中倒数第二个元素时失败了 . 例如,如果您有一个10个元素的数组,并尝试使用以下方法删除第9个元素:
最终得到一个8元素阵列 . 不知道为什么,但我确认John的原始实现没有这个问题 .
Underscore.js可用于解决多个浏览器的问题 . 它使用内置浏览器方法(如果存在) . 如果它们不存在,就像旧的Internet Explorer版本一样,它使用自己的自定义方法 .
从数组中删除元素的简单示例(来自网站):
找到要删除的数组元素的
index
,然后使用splice删除该索引 .splice
的第二个参数是要删除的元素数 . 请注意splice
修改了数组并返回一个包含已删除元素的新数组 .Note :browser support for indexOf有限; Internet Explorer 7和8不支持它 .
如果您在不受支持的浏览器中需要
indexOf
,请尝试以下polyfill
. 查找有关此polyfill here的更多信息 .基于所有主要正确的答案并考虑到建议的最佳实践(特别是不直接使用Array.prototype),我想出了以下代码:
回顾上述功能,尽管它工作正常,但我意识到可能会有一些性能提升 . 使用ES6而不是ES5也是一种更好的方法 . 为此,这是改进的代码:
如何使用:
我目前正在撰写一篇博文,其中我对Array的几个解决方案进行了基准测试,没有遇到任何问题,并比较了运行所需的时间 . 完成该帖后,我将使用链接更新此答案 . 只是为了让你知道,我已经将上述内容与lodash进行了比较,如果浏览器支持
Map
,它就会超过lodash!请注意,我没有使用Array.prototype.indexOf
或Array.prototype.includes
将_l3362_或Object
中的exlcudeValues包装起来,使查询速度更快!有两种主要方法:
splice() :
anArray.splice(index, 1);
delete :
delete anArray[index];
对数组使用delete时要小心 . 删除对象的属性但对数组不太好 . 最好将
splice
用于数组 .请记住,当您使用
delete
作为数组时,anArray.length
可能会得到错误的结果 . 换句话说,delete
将删除元素但不会更新length属性的值 .使用删除后,您还可能会在索引号中出现漏洞,例如:你可能最终得到索引1,3,4,8,9,11和使用删除之前的长度 . 在这种情况下,所有索引的
for
循环都会崩溃,因为索引不再是顺序的 .如果由于某种原因被迫使用
delete
,那么当需要循环遍历数组时,应该使用for each循环 . 事实上,如果可能的话,总是避免使用索引for循环 . 这样,代码将更加健壮,并且不易出现索引问题 .一种更现代的方式,以前称为Harmony或ES 6 . 鉴于:
然后:
产量:
您可以使用Babel和polyfill service来确保跨浏览器良好支持 .
取决于你是否想留空 .
如果你想要一个空插槽,删除就可以了:
如果你不这样做,你应该使用splice方法:
如果你需要该项的值,你可以只存储返回的数组的元素:
如果你想按某种顺序进行,你可以使用
array.pop()
作为最后一个,或者array.shift()
作为第一个(并且都返回项目的值) .如果您不知道项目的索引,可以使用
array.indexOf( item )
来获取它(在if()
中获取一个项目或在while()
中获取所有项目) .array.indexOf( item )
返回索引,如果未找到则返回-1 .我还有另一个从数组中删除的好方法:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
于2016年10月编辑
简单,直观和明确(https://en.wikipedia.org/wiki/Occam%27s_razor)
不可变(原始数组保持不变)
如果您的浏览器不支持标准JS函数,请执行此操作 - use polyfill
在这个代码示例中,我使用 "array.filter(...)" 函数从数组中删除不需要的项目,此函数不支持此功能(例如版本9之前的IE或版本1.5之前的Firefox),请考虑使用the filter polyfill from Mozilla .
删除项目(ECMA-262 Edition 5 code aka oldstyle JS)
删除项目(ES2015代码)
IMPORTANT ES2015 "() => {}"在IE浏览器中根本不支持箭头功能语法,Chrome在45版本之前,Firefox之前是22版本,Safari之前是10版本 . 要在旧版浏览器中使用ES2015语法,您可以使用BabelJS
删除多个项目(ES2016代码)
此方法的另一个优点是您可以删除多个项目
IE完全不支持 IMPORTANT "array.includes(...)"功能,47版之前的Chrome,43版本之前的Firefox,9版本之前的Safari以及14之前版本的Edge所以here is polyfill from Mozilla
删除多个项目(尖端实验性JavaScript ES2018?)
Try it yourself in BabelJS :)
Reference
Array.prototype.includes
This-Binding Syntax Proposal
Functional composition
ES6&无突变:(2016年10月)
然后 :
一位朋友在Internet Explorer 8遇到了问题,并告诉我他做了什么 . 我告诉他这是错的,他告诉我他在这里得到了答案 . 当前的最佳答案不适用于所有浏览器(例如Internet Explorer 8),它只会删除第一次出现的项目 .
从数组中删除所有实例
它向后循环遍历数组(因为索引和长度将随着项目的移除而改变)并删除项目(如果已找到) . 它适用于所有浏览器 .
如果元素有多个实例,则可以执行向后循环以确保不会搞砸索引 .
现场演示
我知道已有很多答案,但其中许多似乎使问题复杂化 . 这是一种删除键的所有实例的简单递归方法 - 调用self直到找不到索引 . 是的,它只能在带有
indexOf
的浏览器中使用,但它很简单,可以很容易地进行填充 .Stand-alone function
Prototype method