remove - 如何从JavaScript中删除数组中的特定元素?




splice js (20)

我有一个整数数组,我正在使用.push()方法向其中添加元素。

有没有一种简单的方法从数组中删除特定元素? 相当于像array.remove(int);

我必须使用核心 JavaScript - 不允许使用框架。

https://code.i-harness.com


ES6和无突变:( 2016年10月)

const removeByIndex = (list, index) =>
  [
    ...list.slice(0, index),
    ...list.slice(index + 1)
  ];

然后 :

removeByIndex([33,22,11,44],1) //=> [33,11,44]

编辑于2016年10月

在这个代码示例中,我使用“array.filter(...)”函数从数组中删除不需要的项,此函数不会更改原始数组并创建新数组。 如果您的浏览器不支持此功能(例如版本9之前的IE或版本1.5之前的Firefox),请考虑使用Mozilla中的过滤器polyfill

删除项目(ECMA-262 Edition 5 code aka oldstyle JS)

var value = 3

var arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(function(item) { 
    return item !== value
})

console.log(arr)
// [ 1, 2, 4, 5 ]

删除项目(ES2015代码)

let value = 3

let arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(item => item !== value)

console.log(arr)
// [ 1, 2, 4, 5 ]

重要事项 ES2015“()=> {}”IE中根本不支持箭头功能语法,Chrome版本为45版本,Firefox版本为22版本,Safari版本为10版本。 要在旧浏览器中使用ES2015语法,您可以使用BabelJS

删除多个项目(ES2016代码)

此方法的另一个优点是您可以删除多个项目

let forDeletion = [2, 3, 5]

let arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(item => !forDeletion.includes(item))
// !!! Read below about array.includes(...) support !!!

console.log(arr)
// [ 1, 4 ]

重要信息 IE中根本不支持“array.includes(...)”功能,47版本之前的Chrome版本,43版本之前的Firefox版本,9版本之前的Safari版本以及14版本之前的Edge版本所以这里是来自Mozilla的polyfill

删除多个项目(尖端实验性JavaScript ES2018?)

// array-lib.js

export function remove(...forDeletion) {
    return this.filter(item => !forDeletion.includes(item))
}

// main.js

import { remove } from './array-lib.js'

let arr = [1, 2, 3, 4, 5, 3]

// :: This-Binding Syntax Proposal
// using "remove" function as "virtual method"
// without extending Array.prototype
arr = arr::remove(2, 3, 5)

console.log(arr)
// [ 1, 4 ]

在BabelJS中自己尝试:)

参考


Underscore.js可用于解决多个浏览器的问题。 它使用内置浏览器方法(如果存在)。 如果它们不存在,就像旧的Internet Explorer版本一样,它使用自己的自定义方法。

从数组中删除元素的简单示例(来自网站):

_.without([1, 2, 1, 0, 3, 1, 4], 0, 1); // => [2, 3, 4]

好的,例如你有以下数组:

var num = [1, 2, 3, 4, 5];

我们想删除4号,你可以简单地做下面的代码:

num.splice(num.indexOf(4), 1); //num will be [1, 2, 3, 5];

如果重新使用此函数,则编写一个可重用的函数,该函数将附加到Native数组函数,如下所示:

Array.prototype.remove = Array.prototype.remove || function(x) {
  const i = this.indexOf(x);
  if(i===-1) return;
  this.splice(i, 1); //num.remove(5) === [1, 2, 3];
}

但是,如果您使用下面的数组而不是数组中的[5] s,那怎么样?

var num = [5, 6, 5, 4, 5, 1, 5];

我们需要一个循环来检查所有这些,但更容易和更有效的方法是使用内置的JavaScript函数,所以我们编写一个使用过滤器的函数,如下所示:

const _removeValue = (arr, x) => arr.filter(n => n!==x);
//_removeValue([1, 2, 3, 4, 5, 5, 6, 5], 5) //return [1, 2, 3, 4, 6]

还有第三方库可以帮助你做这些,比如Lodash或Underscore,有关更多信息,请查看lodash _.pull,_.pullAt或_.without。


一位朋友在Internet Explorer 8遇到问题,并向我展示了他的所作所为。 我告诉他这是错的,他告诉我他在这里得到了答案。 当前的最佳答案不适用于所有浏览器(例如Internet Explorer 8),它只会删除第一次出现的项目。

从数组中删除所有实例

function remove(arr, item) {
    for (var i = arr.length; i--;) {
        if (arr[i] === item) {
            arr.splice(i, 1);
        }
    }
}

它向后循环遍历数组(因为索引和长度将随着项目的移除而改变)并删除项目(如果已找到)。 它适用于所有浏览器。


以下是使用JavaScript从数组中删除项目的几种方法。

所描述的所有方法都不会改变原始数组 ,而是创建一个新数组

如果您知道项目的索引

假设您有一个数组,并且想要移除位置i中的项目。

一种方法是使用slice()

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const i = 3
const filteredItems = items.slice(0, i-1).concat(items.slice(i, items.length))

console.log(filteredItems)

slice()使用它接收的索引创建一个新数组。 我们只是创建一个新数组,从开始到我们想要删除的索引,并从我们删除的数据到数组末尾之后的第一个位置连接另一个数组。

如果你知道价值

在这种情况下,一个不错的选择是使用filter() ,它提供了更具说明性的方法:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(item => item !== valueToRemove)

console.log(filteredItems)

这使用ES6箭头功能。 您可以使用传统功能来支持旧版浏览器:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(function(item) {
  return item !== valueToRemove
})

console.log(filteredItems)

或者您可以使用Babel并将ES6代码转发回ES5,使其更易于浏览旧浏览器,同时在代码中编写现代JavaScript。

删除多个项目

如果不是单个项目,您想要删除多个项目,该怎么办?

让我们找到最简单的解决方案。

按索引

您只需创建一个函数并删除系列中的项目:

const items = ['a', 'b', 'c', 'd', 'e', 'f']

const removeItem = (items, i) =>
  items.slice(0, i-1).concat(items.slice(i, items.length))

let filteredItems = removeItem(items, 3)
filteredItems = removeItem(filteredItems, 5)
//["a", "b", "c", "d"]

console.log(filteredItems)

按价值

您可以在回调函数中搜索包含:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valuesToRemove = ['c', 'd']
const filteredItems = items.filter(item => !valuesToRemove.includes(item))
// ["a", "b", "e", "f"]

console.log(filteredItems)

避免改变原始数组

splice() (不要与slice()混淆)改变原始数组,应该避免。

(最初发布于https://flaviocopes.com/how-to-remove-item-from-array/


你有1到9个数组,你想删除5使用下面的代码。

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var newNumberArray = numberArray.filter(m => {
  return m !== 5;
});

console.log("new Array, 5 removed", newNumberArray);

如果你想要多个值ex: - 1,7,8

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var newNumberArray = numberArray.filter(m => {
  return (m !== 1) && (m !== 7) && (m !== 8);
});

console.log("new Array, 5 removed", newNumberArray);

如果要删除数组ex中的数组值: - [3,4,5]

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var removebleArray = [3,4,5];

var newNumberArray = numberArray.filter(m => {
    return !removebleArray.includes(m);
});

console.log("new Array, [3,4,5] removed", newNumberArray);

包括支持的浏览器是link


你永远不应该在你的数组中改变你的数组。 因为这是针对功能编程模式的。 你可以做的是创建一个新的数组,而不引用你想要使用es6方法filter更改数据的数组;

var myArray = [1,2,3,4,5,6];

假设您要从数组中删除5 ,您可以像这样简单地执行此操作。

myArray = myArray.filter(value => value !== 5);

这将为您提供一个没有您想要删除的值的新数组。 结果将是

 [1,2,3,4,6]; // 5 has been removed from this array

为了进一步理解,您可以阅读Array.filter上的MDN文档filter


基于所有主要正确的答案并考虑到建议的最佳实践(特别是不直接使用Array.prototype),我想出了以下代码:

function arrayWithout(arr, values) {
  var isArray = function(canBeArray) {
    if (Array.isArray) {
      return Array.isArray(canBeArray);
    }
    return Object.prototype.toString.call(canBeArray) === '[object Array]';
  };

  var excludedValues = (isArray(values)) ? values : [].slice.call(arguments, 1);
  var arrCopy = arr.slice(0);

  for (var i = arrCopy.length - 1; i >= 0; i--) {
    if (excludedValues.indexOf(arrCopy[i]) > -1) {
      arrCopy.splice(i, 1);
    }
  }

  return arrCopy;
}

回顾上述功能,尽管它工作正常,但我意识到可能会有一些性能提升。使用ES6而不是ES5也是一种更好的方法。为此,这是改进的代码:

const arrayWithoutFastest = (() => {
  const isArray = canBeArray => ('isArray' in Array) 
    ? Array.isArray(canBeArray) 
    : Object.prototype.toString.call(canBeArray) === '[object Array]';

  let mapIncludes = (map, key) => map.has(key);
  let objectIncludes = (obj, key) => key in obj;
  let includes;

  function arrayWithoutFastest(arr, ...thisArgs) {
    let withoutValues = isArray(thisArgs[0]) ? thisArgs[0] : thisArgs;

    if (typeof Map !== 'undefined') {
      withoutValues = withoutValues.reduce((map, value) => map.set(value, value), new Map());
      includes = mapIncludes;
    } else {
      withoutValues = withoutValues.reduce((map, value) => { map[value] = value; return map; } , {}); 
      includes = objectIncludes;
    }

    const arrCopy = [];
    const length = arr.length;

    for (let i = 0; i < length; i++) {
      // If value is not in exclude list
      if (!includes(withoutValues, arr[i])) {
        arrCopy.push(arr[i]);
      }
    }

    return arrCopy;
  }

  return arrayWithoutFastest;  
})();

如何使用:

const arr = [1,2,3,4,5,"name", false];

arrayWithoutFastest(arr, 1); // will return array [2,3,4,5,"name", false]
arrayWithoutFastest(arr, 'name'); // will return [2,3,4,5, false]
arrayWithoutFastest(arr, false); // will return [2,3,4,5]
arrayWithoutFastest(arr,[1,2]); // will return [3,4,5,"name", false];
arrayWithoutFastest(arr, {bar: "foo"}); // will return the same array (new copy)

我目前正在撰写一篇博文,其中我对Array的几个解决方案进行了基准测试,没有遇到任何问题,并比较了运行所需的时间。完成该帖后,我将使用链接更新此答案。只是为了让你知道,我已经将上面的内容与lodash的内容进行了比较,如果浏览器不支持Map,它就胜过了lodash!请注意,我没有使用Array.prototype.indexOfArray.prototype.includes包含exlcudeValues MapObject更快地查询!(https://jsperf.com/array-without-benchmark-against-lodash


太老了回复,但可能通过提供谓词而不是值来帮助某人。

注意:它将更新给定的数组,并返回受影响的行

用法

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;
    }
};

如果要删除已删除位置的新数组,可以始终删除特定元素并过滤掉数组。 对于没有实现过滤方法的浏览器,可能需要对数组对象进行扩展,但从长远来看,它更容易,因为你所做的只是:

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]


如果阵列中有复杂对象,可以使用过滤器吗? 在$ .inArray或array.splice不那么容易使用的情况下。 特别是如果对象在数组中可能很浅。

例如,如果您有一个带有Id字段的对象,并且您希望从数组中删除该对象:

this.array = this.array.filter(function(element, i) {
    return element.id !== idToRemove;
});

您可以使用ES6。

var array=['1','2','3','4','5','6']
var index = array.filter((value)=>value!='3');

输出:

["1", "2", "4", "5", "6"]

我不知道你期望array.remove(int)如何表现。 我可以想到你可能想要的三种可能性。

要在索引i处删除数组的元素:

array.splice(i, 1);

如果要从数组中删除具有值number每个元素:

for(var i = array.length - 1; i >= 0; i--) {
    if(array[i] === number) {
       array.splice(i, 1);
    }
}

如果您只想使索引i处的元素不再存在,但您不希望其他元素的索引发生更改:

delete array[i];

我知道已有很多答案,但其中许多似乎使问题复杂化。 这是一种删除键的所有实例的简单递归方法 - 调用self直到找不到索引。 是的,它仅适用于具有indexOf浏览器,但它很简单,并且可以轻松地进行多边形填充。

独立功能

function removeAll(array, key){
    var index = array.indexOf(key);

    if(index === -1) return;

    array.splice(index, 1);
    removeAll(array,key);
}

原型方法

Array.prototype.removeAll = function(key){
    var index = this.indexOf(key);

    if(index === -1) return;

    this.splice(index, 1);
    this.removeAll(key);
}

我还有另一个从数组中删除的好方法:

var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]

filter


无需使用indexOfsplice 。 但是,如果您只想删除一个元素,它会表现得更好。

查找并移动(移动):

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;
}

使用indexOfsplice (indexof):

function indexof(arr, val) {
  var i;
  while ((i = arr.indexOf(val)) != -1) {
    arr.splice(i, 1);
  }
}

仅使用splice (拼接):

function splice(arr, val) {
  for (var i = arr.length; i--;) {
    if (arr[i] === val) {
      arr.splice(i, 1);
    }
  }
}

nodejs上运行时间为1000个元素(平均超过10000次运行)的数组:

indexof移动慢大约10倍。 即使通过在splice中删除对indexOf的调用来改进它,它也比移动更糟糕。

Remove all occurrences:
    move 0.0048 ms
    indexof 0.0463 ms
    splice 0.0359 ms

Remove first occurrence:
    move_one 0.0041 ms
    indexof_one 0.0021 ms

更现代的ECMAScript 2015 (以前称为Harmony或ES 6)方法。 鉴于:

const items = [1, 2, 3, 4];
const index = 2;

然后:

items.filter((x, i) => i !== index);

产量:

[1, 2, 4]

您可以使用Babelpolyfill服务来确保跨浏览器能够很好地支持它。


看看这段代码。 它适用于所有主流浏览器

remove_item = function (arr, value) {
    var b = '';
    for (b in arr) {
        if (arr[b] === value) {
            arr.splice(b, 1);
            break;
        }
    }
    return arr;
}

调用此功能

remove_item(array,value);

  Array.prototype.removeItem = function(a) {
            for (i = 0; i < this.length; i++) {
                if (this[i] == a) {
                    for (i2 = i; i2 < this.length - 1; i2++) {
                        this[i2] = this[i2 + 1];
                    }
                    this.length = this.length - 1
                    return;
                }
            }
        }

    var recentMovies = ['Iron Man', 'Batman', 'Superman', 'Spiderman'];
    recentMovies.removeItem('Superman');






arrays