Как удалить определенный элемент из массива в JavaScript?

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

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

Я должен использовать основной JavaScript - рамки не допускаются.

Ответы

Ответ 1

Найдите index элемента массива, который вы хотите удалить, а затем удалите этот индекс с помощью splice.

Метод splice() изменяет содержимое массива, удаляя существующие элементы и/или добавление новых элементов.

var array = [2, 5, 9];
console.log(array)
var index = array.indexOf(5);
if (index > -1) {
  array.splice(index, 1);
}
// array = [2, 9]
console.log(array);

Ответ 2

Я не знаю, как вы ожидаете, что 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];

Ответ 3

Отредактировано в октябре 2016 года

  • Сделайте это просто, интуитивно понятно и понятно (Бритва Оккама)
  • Сделайте это неизменным (исходный массив остается неизменным)
  • Сделайте это с помощью стандартных функций JavaScript, если ваш браузер их не поддерживает - используйте polyfill

В этом примере кода я использую функцию "array.filter(...)" для удаления ненужных элементов из массива. Эта функция не меняет исходный массив и создает новый. Если ваш браузер не поддерживает эту функцию (например, Internet Explorer до версии 9 или Firefox до версии 1.5), рассмотрите возможность использования фильтра полифильтра из Mozilla.

Удаление элемента (код ECMA-262 Edition 5, также известный как старый стиль JavaScript)

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 ]

Удаление элемента (код ECMAScript 6)

let value = 3

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

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

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

ВАЖНО ECMAScript 6 "() => {}" Синтаксис функции стрелок вообще не поддерживается в Internet Explorer, Chrome до 45 версии, Firefox до 22 версии и Safari до 10 версии. Чтобы использовать синтаксис ECMAScript 6 в старых браузерах, вы можете использовать BabelJS.


Удаление нескольких элементов (код ECMAScript 7)

Дополнительным преимуществом этого метода является то, что вы можете удалить несколько элементов

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 ]

ВАЖНО Функция "array.includes(...)" вообще не поддерживается в Internet Explorer, Chrome до 47 версии, Firefox до 43 версии, Safari до 9 версии и Edge до 14 версии, так что Вот полифилл от Mozilla.

Удаление нескольких элементов (возможно, в будущем)

Если предложение "This-Binding Syntax" когда-либо будет принято, вы сможете сделать это:

// 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 :)

Ссылка

Ответ 4

Это зависит от того, хотите ли вы оставить пустое место или нет.

Если вам нужен пустой слот, удаление возможно:

delete array[index];

Если вы этого не сделаете, вам следует использовать метод сращивания :

array.splice(index, 1);

И если вам нужно значение этого элемента, вы можете просто сохранить возвращенный элемент массива:

var value = array.splice(index, 1)[0];

Если вы хотите сделать это в каком-то порядке, вы можете использовать array.pop() для последнего или array.shift() для первого (и оба возвращают значение элемента тоже).

И если вы не знаете индекс предмета, вы можете использовать array.indexOf(item), чтобы получить его (в if(), чтобы получить один предмет, или в while(), чтобы получить их все). array.indexOf(item) возвращает либо индекс, либо -1, если не найден.

Ответ 5

У друга были проблемы в Internet Explorer 8 и он показал мне, что он сделал. Я сказал ему, что это неправильно, и он сказал мне, что получил ответ здесь. Текущий верхний ответ не будет работать во всех браузерах (например, Internet Explorer 8), и он будет удалять только первое вхождение элемента.

Удалить ВСЕ экземпляры из массива

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

Он перебирает массив в обратном направлении (поскольку индексы и длина изменяются при удалении элементов) и удаляет элемент, если он найден. Работает во всех браузерах.

Ответ 6

Есть два основных подхода:

  1. splice(): anArray.splice(index, 1);

  2. удалить: delete anArray[index];

Будьте осторожны, когда вы используете delete для массива. Это хорошо для удаления атрибутов объектов, но не так хорошо для массивов. Лучше использовать splice для массивов.

Помните, что когда вы используете delete для массива, вы можете получить неверные результаты для anArray.length. Другими словами, delete удалит элемент, но не обновит значение свойства length.

Вы также можете ожидать наличия дыр в индексах после использования delete, например, вы можете получить индексы 1, 3, 4, 8, 9 и 11 и длину, как это было до использования delete. В этом случае все проиндексированные циклы for аварийно завершат работу, поскольку индексы больше не являются последовательными.

Если вы по какой-то причине вынуждены использовать delete, то вам следует использовать циклы for each, когда вам нужно циклически проходить по массивам. На самом деле, всегда избегайте использования индексированных циклов for, если это возможно. Таким образом, код будет более устойчивым и менее подверженным проблемам с индексами.

Ответ 7

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)

Ответ 8

Нет необходимости использовать indexOf или splice. Однако он работает лучше, если вы хотите удалить только одно вхождение элемента.

Найти и переместить (переместить):

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

Используйте indexOf и splice (indexof):

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

Использовать только splice (splice):

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

Время выполнения на nodejs для массива с 1000 элементов (в среднем более 10000 запусков):

indexof примерно в 10 раз медленнее, чем двигаться. Даже если его улучшить, удалив вызов indexOf в splice, он работает намного хуже, чем move.

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

Ответ 9

Самый простой способ:

var index = array.indexOf(item);
if(index != -1)
    array.splice( index, 1 );

Ответ 10

Это обеспечивает предикат вместо значения.

ПРИМЕЧАНИЕ. обновит указанный массив и вернет затронутые строки.

Использование
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;
    }
};

Ответ 11

Джон Резиг опубликовал хорошую реализацию:

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

Если вы не хотите расширять глобальный объект, вместо этого вы можете сделать что-то вроде следующего:

// Array Remove - By John Resig (MIT Licensed)
Array.remove = function(array, from, to) {
    var rest = array.slice((to || from) + 1 || array.length);
    array.length = from < 0 ? array.length + from : from;
    return array.push.apply(array, rest);
};

Но главная причина, по которой я публикую это, состоит в том, чтобы предостеречь пользователей от альтернативной реализации, предложенной в комментариях на этой странице (14 декабря 2007 г.):

Array.prototype.remove = function(from, to){
  this.splice(from, (to=[0,from||1,++to-from][arguments.length])<0?this.length+to:to);
  return this.length;
};

Поначалу кажется, что он работает хорошо, но через болезненный процесс, который я обнаружил, он терпит неудачу при попытке удалить второй или последний элемент в массиве. Например, если у вас есть массив из 10 элементов, и вы пытаетесь удалить 9-й элемент следующим образом:

myArray.remove(8);

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

Ответ 12

Это легко сделать с помощью метода фильтра :

function remove(arrOriginal, elementToRemove){
    return arrOriginal.filter(function(el){return el !== elementToRemove});
}
console.log(remove([1, 2, 1, 0, 3, 1, 4], 1));

Это удаляет все элементы из массива, а также работает быстрее, чем комбинация slice и indexOf.

Ответ 13

Underscore.js можно использовать для решения проблем с несколькими браузерами. Он использует встроенные методы браузера, если таковые имеются. Если они отсутствуют, как в случае более старых версий Internet Explorer, он использует свои собственные пользовательские методы.

Простой пример удаления элементов из массива (с сайта):

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

Ответ 14

Если вы хотите новый массив с удаленными удаленными позициями, вы всегда можете удалить определенный элемент и отфильтровать массив. Возможно, потребуется расширение объекта массива для браузеров, которые не реализуют метод фильтра, но в долгосрочной перспективе это проще, поскольку все, что вы делаете, это:

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

Ответ 15

Вы можете использовать ES6. Например, чтобы удалить значение "3" в этом случае:

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

Вывод:

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

Ответ 16

Проверьте этот код. Это работает в любом крупном браузере.

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

Ответ 17

Вы можете использовать lodash _.pull (массив мутирования), _.pullAt (массив мутирования) или _.without (не мутирует массив),

var array1 = ['a', 'b', 'c', 'd']
_.pull(array1, 'c')
console.log(array1) // ['a', 'b', 'd']

var array2 = ['e', 'f', 'g', 'h']
_.pullAt(array2, 0)
console.log(array2) // ['f', 'g', 'h']

var array3 = ['i', 'j', 'k', 'l']
var newArray = _.without(array3, 'i') // ['j', 'k', 'l']
console.log(array3) // ['i', 'j', 'k', 'l']

Ответ 18

Хорошо, например, у вас есть массив ниже:

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

И мы хотим удалить номер 4. Вы можете просто использовать следующий код:

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

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

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] в массиве?

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.

Ответ 19

Вот несколько способов удалить элемент из массива с помощью JavaScript.

Все описанные методы не изменяют исходный массив, а создают новый.

Если вы знаете индекс предмета

Предположим, у вас есть массив, и вы хотите удалить элемент в позиции i.

Одним из методов является использование slice():

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

console.log(filteredItems)

Ответ 20

Я новичок в JavaScript и мне нужна эта функциональность. Я просто написал это:

function removeFromArray(array, item, index) {
  while((index = array.indexOf(item)) > -1) {
    array.splice(index, 1);
  }
}

Тогда, когда я хочу использовать это:

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

У вас могут быть другие потребности, чем у меня, поэтому вы можете легко изменить их в соответствии с их потребностями. Я надеюсь, что это помогает кому-то.

Ответ 21

ES6 и без мутации: (октябрь 2016 г.)

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

Затем:

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

Ответ 22

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

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

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

Ответ 23

Обновление: этот метод рекомендуется, только если вы не можете использовать 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]

Ответ 24

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

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]

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

Ответ 25

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

Ответ 26

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

Ответ 27

Удаление определенного элемента/строки из массива может быть сделано в одну строку: Я все еще думаю, что это самая элегантная строчка, которую вы можете получить для такого рода проблем:

theArray.splice(theArray.indexOf("stringToRemoveFromArray"), 1);

где theArray - массив, из которого вы хотите удалить что-то конкретное, stringToRemoveFromArray - строка, которую вы хотите удалить, а 1 - количество элементов, которые вы хотите удалить.

Ответ 28

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

Ответ 29

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

Ответ 30

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

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