Как удалить определенный элемент из массива в JavaScript? - PullRequest
7275 голосов
/ 24 апреля 2011

У меня есть массив Numbers, и я использую метод .push() для добавления в него элементов.

Есть ли простой способ удалить определенный элемент из массива?Эквивалент чего-то вроде array.remove(number);.

Мне нужно использовать core JavaScript - нет фреймворки разрешены.

Ответы [ 79 ]

23 голосов
/ 13 марта 2013

Обновление: Этот метод рекомендуется, только если вы не можете использовать ECMAScript 2015 (ранее известный как ES6). Если вы можете использовать его, другие ответы здесь обеспечивают более аккуратные реализации.


Эта суть здесь решит вашу проблему, а также удалит все вхождения аргумента вместо 1 (или указанного значения).

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

Использование:

var x = [1, 2, 3, 3, true, false, undefined, false];

x.destroy(3);         // => 3
x.destroy(false);     // => false
x;                    // => [1, 2, true, undefined]

x.destroy(true);      // => true
x.destroy(undefined); // => undefined
x;                    // => [1, 2]

x.destroy(3);         // => null
x;                    // => [1, 2]
22 голосов
/ 09 апреля 2015

Если у вас есть сложные объекты в массиве, вы можете использовать фильтры? В ситуациях, когда $ .inArray или array.splice не так просты в использовании. Особенно если объекты, возможно, мелкие в массиве.

например. если у вас есть объект с полем Id и вы хотите, чтобы объект был удален из массива:

this.array = this.array.filter(function(element, i) {
    return element.id !== idToRemove;
});
21 голосов
/ 30 октября 2018

Я хочу ответить на основании ES6.Предположим, у вас есть массив, как показано ниже:

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

Если вы хотите удалить специальный индекс, такой как 2, напишите код ниже:

arr.splice(2, 1); //=> arr became [1,2,4]

Но если вы хотите удалить специальный элементкак 3, и вы не знаете, что его индекс работает следующим образом:

arr = arr.filter(e => e !== 3); //=> arr became [1,2,4]

Подсказка : пожалуйста, используйте функцию стрелки для обратного вызова фильтра, если вы не получите пустой массив.

19 голосов
/ 26 декабря 2017

Вы никогда не должны мутировать ваш массив.Как это против функционального шаблона программирования.Что вы можете сделать, это создать новый массив без ссылки на массив, для которого вы хотите изменить данные, используя метод 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

. Для дальнейшего понимания вы можете прочитать документацию MDN на Array.filter https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

18 голосов
/ 25 апреля 2016

Более современный, ECMAScript 2015 (ранее известный как Harmony или ES 6) подход. Дано:

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

Тогда:

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

Выход:

[1, 2, 4]

Вы можете использовать Babel и polyfill service , чтобы обеспечить его хорошую поддержку во всех браузерах.

16 голосов
/ 03 февраля 2014

Я знаю, что ответов уже много, но многие из них, кажется, слишком усложняют проблему.Вот простой рекурсивный способ удаления всех экземпляров ключа - вызывает 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);
}
15 голосов
/ 05 июня 2018

У меня есть еще одно хорошее решение для удаления из массива:

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"]

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

15 голосов
/ 12 августа 2013

Вы можете сделать обратный цикл, чтобы убедиться, что индексы не испорчены, если имеется несколько экземпляров элемента.

var myElement = "chocolate";
var myArray = ['chocolate', 'poptart', 'poptart', 'poptart', 'chocolate', 'poptart', 'poptart', 'chocolate'];

/* Important code */
for (var i = myArray.length - 1; i >= 0; i--) {
    if (myArray[i] == myElement) myArray.splice(i, 1);
}

Live Demo

15 голосов
/ 07 августа 2018

У вас есть массив от 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);

Если вы хотите получить несколько значений, например: - 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);

Если вы хотите удалить значение массива в массиве, например: - [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);

включает в себя поддерживаемый браузер ссылка

15 голосов
/ 28 января 2014

Основываясь на всех ответах, которые были в основном правильными, и с учетом лучших рекомендаций (особенно без непосредственного использования 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.indexOf или Array.prototype.includes, поскольку обертывание значений exlcudeValues ​​в Map или Object делает запросы быстрее!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...