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

6774

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

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

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

  • 90
    Если вам нужно поддержать <IE9 ( вздох ), тогда проверьте этот вопрос SO относительно indexOf в IE.
  • 21
    (lodash) array = ['a', 'b', 'c']; _.pull (array, 'a') // array => ['b', 'c']; Смотрите также stackoverflow.com/questions/5767325/…
Показать ещё 4 комментария
Теги:
arrays

77 ответов

10253
Лучший ответ

Найдите 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);

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


Примечание: поддержка браузера для indexOf ограничена; это не поддерживается в Internet Explorer 7 и 8.

Если вам нужен indexOf в неподдерживаемом браузере, попробуйте следующий polyfill. Найти больше информации об этом polyfill здесь.

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
});
  • 11
    @ Питер, да, возможно, ты прав. Эта статья объясняет больше и имеет обходной путь для несовместимых браузеров: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
  • 4
    Вы можете упростить его использование, добавив функцию delete в прототип массива. Я использовал ваш пример в гисте, который удаляет все целевые элементы в массиве вместо 1.
Показать ещё 36 комментариев
990

Я не знаю, как вы ожидаете, что 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];
  • 273
    delete не является правильным способом удаления элемента из массива!
  • 57
    @FelixKling Зависит от того, работает ли это, если вы хотите сделать так, чтобы array.hasOwnProperty(i) возвращал false и чтобы элемент в этой позиции возвращал undefined . Но я признаю, что это не очень распространенная вещь, которую хочется делать.
Показать ещё 17 комментариев
854

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

  • Сделайте это просто, интуитивно понятно и явно (https://en.wikipedia.org/wiki/Occam%27s_razor)
  • Сделайте это неизменным (исходный массив остается неизменным)
  • Сделайте это с помощью стандартных функций JS, если ваш браузер их не поддерживает - используйте polyfill

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

Извлечение элемента (ECMA-262 Edition 5 код, также известный как 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 ]

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

Удаление нескольких элементов (передовой экспериментальный 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 ]

50&builtIns=false&code= function remove(...forDeletion) { return this.filter(item => !forDeletion.includes(item)) } let arr = [1, 2, 3, 4, 5, 3] //:: This-Binding Syntax Proposal //using remove function as "virtual method" arr = arr::remove(2, 3, 5) console.log(arr) //[ 1, 4 ] rel=noreferrer> Попробуйте сами в BabelJS :)

Ссылка

  • 4
    но иногда мы хотим удалить элемент из исходного массива (неизменяемый), например, массив, используемый в директиве Angular 2 * ngFor
  • 30
    Лучше, чем принятое решение, потому что оно не предполагает единственного совпадения и предпочтительна неизменность
Показать ещё 13 комментариев
362

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

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

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, если не найден.

  • 48
    Стоит отметить, что var value будет хранить не удаленное значение, а массив, содержащий удаленное значение.
  • 20
    delete не является правильным способом удаления элемента из массива !!
Показать ещё 3 комментария
237

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

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

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

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

  • 9
    @ sroes это не должно быть, потому что цикл начинается с i = arr.length -1 или i-- делая его таким же, как индекс max. arr.length это просто начальное значение для i . i-- всегда буду правдивым (и уменьшаться на 1 при каждой операции цикла) до тех пор, пока он не станет равным 0 (ложное значение), и цикл затем остановится.
  • 1
    Вторая функция довольно неэффективна. На каждой итерации indexOf будет начинать поиск с начала массива.
Показать ещё 6 комментариев
147

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

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

  2. delete: delete anArray[index];

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

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

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

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

111
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)
  • 13
    Я не большой поклонник такого подхода. Если вы в конечном итоге используете разные библиотеки или платформы, они могут конфликтовать друг с другом.
  • 0
    Это также сработало, но я решил в конце пойти с функцией indexOf. Спасибо за помощь!
Показать ещё 4 комментария
86

Нет необходимости использовать 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
  • 3
    Похоже, что метод 'move', представленный здесь, должен работать во всех браузерах, а также избегать создания дополнительного массива; большинство других решений здесь имеют одну или обе из этих проблем. Я думаю, что этот заслуживает гораздо больше голосов, даже если он не выглядит "симпатичным".
77

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

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

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

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

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

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;
    }
};
  • 0
    Я не знаю, что вам нужно проверить -1 (я> -1). Кроме того, я думаю, что эти функции действуют скорее как фильтр, чем как удаление. Если вы передадите row.id === 5, это приведет к массиву только с идентификатором 5, поэтому он выполняет противоположное удаление. Это будет хорошо выглядеть в ES2015: var result = ArrayHelper.remove (myArray, row => row.id === 5);
  • 0
    @WhatWouldBeCool - эта функция изменяет исходный массив и возвращает удаленный элемент вместо копирования результата в новый массив.
55

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

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

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

Вы можете сделать это легко с помощью метода фильтра:

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.

  • 1
    У вас есть источник, что это быстрее?
  • 0
    Хорошее решение. Но, как вы указали, но важно сделать лысым, он не даст тот же результат, что и slice и indexOf, так как он удалит все вхождения 1
Показать ещё 1 комментарий
53

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

// 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 элементов. Не знаю почему, но я подтвердил, что у оригинальной реализации Джона нет этой проблемы.

  • 0
    Просто на собственном опыте узнал, почему стоит всегда использовать Object.prototype.hasOwnProperty ¬¬
38

Вы можете использовать ES6.

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

Выход:

["1", "2", "4", "5", "6"]
  • 2
    Этот ответ хорош, потому что он создает копию исходного массива вместо непосредственного изменения оригинала.
  • 0
    Примечание. Array.prototype.filter - это ECMAScript 5.1 (без IE8). для более конкретных решений: stackoverflow.com/a/54390552/8958729
38

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

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]

35

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

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);
  • 4
    @RolandIllig За исключением использования for in -loop и того факта, что сценарий можно было остановить раньше, возвращая результат из цикла напрямую. Прогнозы разумны;)
  • 0
    Это отличный подход для небольших массивов. Он работает в любом браузере, использует минимальный и интуитивно понятный код, без каких-либо дополнительных сложных каркасов, шайб или поли-заливок.
Показать ещё 1 комментарий
31

ОК, например, у вас есть массив ниже:

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

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

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

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

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.

  • 0
    Есть небольшая опечатка. Пожалуйста исправьте. this.splice(num.indexOf(x), 1); => this.splice(this.indexOf(x), 1);
  • 0
    Пожалуйста, не увеличивайте встроенные модули (присоединяйте функции к Array.prototype) в JavaScript. Это широко считается плохой практикой.
Показать ещё 2 комментария
31

Вы можете использовать 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']
  • 1
    Это не основной JS, как запросил OP, не так ли?
  • 10
    @ some-non-descript-user Вы правы. Но многие пользователи, такие как я, приходят сюда в поисках общего ответа, а не только для ОП.
Показать ещё 1 комментарий
26

Я новичок в 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"]

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

25

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

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

Затем:

removeByIndex([33,22,11,44],1) //=> [33,11,44]
  • 0
    до вверх до вверх вверх вверх вверхууууууууууу! это более актуально, это должен быть ответ № 1, а не № 20 !!!
21

Вот несколько способов удалить элемент из массива с помощью 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/)

  • 0
    Я думаю, что в вашем примере вы хотите items.slice(0, i).concat(items.slice(i+1, items.length)) , (0, i) вместо (0, i-1), потому что массив Элемент 'end' не включен в результат. Кроме того, i + 1 подходит для второй части, так как он возвращает пустой массив, если он выходит за пределы.
21

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

Вы никогда не должны изменять свой массив вашего массива. Как это против функционального шаблона программирования. Что вы можете сделать, это создать новый массив без ссылки на массив, для которого вы хотите изменить данные, используя метод filter es6;

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

19

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

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

this.array = this.array.filter(function(element, i) {
    return element.id !== idToRemove;
});
  • 0
    Вот как мне нравится это делать. Используя функцию стрелки это может быть однострочник. Мне интересно о производительности. Также ничего не стоит, что это заменяет массив. Любой код со ссылкой на старый массив не заметит изменения.
18

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

  • 4
    Обратите внимание, что .filter возвращает новый массив, который отличается от удаления элемента из того же массива. Преимущество этого подхода заключается в том, что вы можете объединять методы массива вместе. Например: [1,2,3].filter(n => n%2).map(n => n*n) === [ 1, 9 ]
  • 0
    Отлично, если у меня есть 600k элементов в массиве и я хочу удалить первые 50k, вы можете себе представить эту медлительность? Это не решение, нужна функция, которая просто удаляет элементы и ничего не возвращает.
Показать ещё 3 комментария
16

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

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

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

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

15

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

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

13
  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');
12

Удалить по индексу

Функция, которая возвращает копию массива без элемента с индексом.

/**
* removeByIndex
* @param {Array} array
* @param {Number} index
*/
function removeByIndex(array, index){
    return array.filter(function(elem, _index){
        return index != _index;
    });
}
l = [1,3,4,5,6,7];
console.log(removeByIndex(l, 1));

$> [ 1, 4, 5, 6, 7 ]

Удалить по значению

Функция, которая возвращает копию массива без значения.

/**
* removeByValue
* @param {Array} array
* @param {Number} value
*/
function removeByValue(array, value){
    return array.filter(function(elem, _index){
        return value != elem;
    });
}
l = [1,3,4,5,6,7];
console.log(removeByValue(l, 5));

$> [ 1, 3, 4, 6, 7]
  • 0
    Являются ли избыточные конструкции нормой для веб-разработчиков? У меня есть кто-то на работе, распыляющий подобные вещи везде. Почему бы просто не return value != elem ?!
11

Создать новый массив:

var my_array = new Array();

Добавьте элементы в этот массив:

my_array.push("element1");

Функция indexOf (возвращает индекс или -1, когда не найден):

var indexOf = function(needle) 
{
    if(typeof Array.prototype.indexOf === 'function') // newer browsers
    {
        indexOf = Array.prototype.indexOf;
    } 
    else // older browsers
    {
        indexOf = function(needle) 
        {
            var index = -1;

            for(var i = 0; i < this.length; i++) 
            {
                if(this[i] === needle) 
                {
                    index = i;
                    break;
                }
            }
            return index;
        };
    }

    return indexOf.call(this, needle);
};

Проверьте индекс этого элемента (проверено с помощью firefox и IE8+):

var index = indexOf.call(my_array, "element1");

Удалить 1 элемент, расположенный по индексу из массива

my_array.splice(index, 1);
10

Я хочу ответить на основе 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]

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

  • 0
    последний вариант вернет пустой массив
  • 0
    @ Dejan.S, я удивлен, какой у тебя массив, и что ты хочешь опустить из своего массива?
Показать ещё 2 комментария
10

Я также столкнулся с ситуацией, когда мне пришлось удалить элемент из Array. .indexOf не работал в IE* поэтому поделился своим рабочим jQuery.inArray().

var index = jQuery.inArray(val,arr);
if (index > -1) {
    arr.splice(index, 1);
    //console.log(arr);
}
  • 0
    jQuery всегда хорош для решения любых кросс-браузерных проблем совместимости различных JavaScript API.
9

2017-05-08

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

const a = {'field': 2} // Non-primitive object
const b = {'field': 2} // Non-primitive object with same value
const c = a            // Non-primitive object that reference the same object as "a"

assert(a !== b) // Don't reference the same item, but have same value
assert(a === c) // Do reference the same item, and have same value (naturally)

//Note: there are many alternative implementations for valuesAreEqual
function valuesAreEqual (x, y) {
   return  JSON.stringify(x) === JSON.stringify(y)
}


//filter will delete false values
//Thus, we want to return "false" if the item
// we want to delete is equal to the item in the array
function removeFromArray(arr, toDelete){
    return arr.filter(target => {return !valuesAreEqual(toDelete, target)})
}

const exampleArray = [a, b, b, c, a, {'field': 2}, {'field': 90}];
const resultArray = removeFromArray(exampleArray, a);

//resultArray = [{'field':90}]

Существуют альтернативные/более быстрые реализации для valuesAreEqual, но это делает работу. Вы также можете использовать пользовательский компаратор, если у вас есть определенное поле для проверки (например, некоторые извлеченные UUID против локального UUID).

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

  • 1
    Мне нравится идея, просто думаю, что немного медленно делать две строки в каждом элементе массива. В любом случае есть случаи, в которых это будет стоить, спасибо, что поделились.
  • 0
    Спасибо, я добавил редактирование, чтобы уточнить, что valuesAreEqual можно заменить. Я согласен, что подход JSON медленный - но он всегда будет работать. Следует определенно использовать лучшее сравнение, когда это возможно.
9

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

Представьте, что вы делаете рекурсивный вызов и вам нужно передать массив с одним элементом меньше, возможно, без текущего индексированного элемента. Или представьте, что вы делаете другой рекурсивный вызов и должны передать массив с нажатым элементом.

Ни в одном из этих случаев вы не можете выполнить myRecursiveFunction(myArr.push(c)) или myRecursiveFunction(myArr.splice(i,1)). Первый идиот фактически передаст длину массива, а второй идиот передаст удаленный элемент в качестве параметра.

Итак, что я делаю на самом деле... Для удаления элемента массива и передачи результата функции в качестве параметра одновременно я делаю следующее

myRecursiveFunction(myArr.slice(0,i).concat(a.slice(i+1)))

Когда дело доходит до того, чтобы подтолкнуть это более глупо... Мне нравится,

myRecursiveFunction((myArr.push(c),myArr))

Я считаю, что в надлежащем функциональном языке метод, изменяющий объект, к которому он обращался, должен возвращать ссылку на сам объект в результате.

8

В CoffeeScript:

my_array.splice(idx, 1) for ele, idx in my_array when ele is this_value
7

Используйте jQuery InArray:

A = [1, 2, 3, 4, 5, 6];
A.splice($.inArray(3, A), 1);
//It will return A=[1, 2, 4, 5, 6]'   

Примечание: inArray вернет -1, если элемент не был найден.

  • 5
    но OP сказал: «Хороший старый JavaScript - рамки не допускаются»
  • 0
    для Chrome 50,0 - A. splice (-1, 1); удалит последний в А.
6

Удалить элемент с индексом i, не изменяя исходный массив:

/**
* removeElement
* @param {Array} array
* @param {Number} index
*/
function removeElement(array, index) {
   return Array.from(array).splice(index, 1);
}

// Another way is
function removeElement(array, index) {
   return array.slice(0).splice(index, 1);
}
6

Ванильный JavaScript (ES5.1) - на месте редакции

Поддержка браузера: Internet Explorer 9 или более поздняя версия (подробная поддержка браузера)

/**
 * Removes all occurences of the item from the array.
 *
 * Modifies the array "in place", i.e. the array passed as an argument
 * is modified as opposed to creating a new array. Also returns the modified
 * array for your convenience.
 */
function removeInPlace(array, item) {
    var foundIndex, fromIndex;

    // Look for the item (the item can have multiple indices)
    fromIndex = array.length - 1;
    foundIndex = array.lastIndexOf(item, fromIndex);

    while (foundIndex !== -1) {
        // Remove the item (in place)
        array.splice(foundIndex, 1);

        // Bookkeeping
        fromIndex = foundIndex - 1;
        foundIndex = array.lastIndexOf(item, fromIndex);
    }

    // Return the modified array
    return array;
}

Vanilla JavaScript (ES5.1) - неизменяемая версия

Поддержка браузера: То же, что и ванильный JavaScript на месте издания

/**
 * Removes all occurences of the item from the array.
 *
 * Returns a new array with all the items of the original array except
 * the specified item.
 */
function remove(array, item) {
    var arrayCopy;

    arrayCopy = array.slice();

    return removeInPlace(arrayCopy, item);
}

Vanilla ES6 - неизменное издание

Поддержка браузера: Chrome 46, Edge 12, Firefox 16, Opera 37, Safari 8 (подробная поддержка браузера)

/**
 * Removes all occurences of the item from the array.
 *
 * Returns a new array with all the items of the original array except
 * the specified item.
 */
function remove(array, item) {
    // Copy the array
    array = [...array];

    // Look for the item (the item can have multiple indices)
    let fromIndex = array.length - 1;
    let foundIndex = array.lastIndexOf(item, fromIndex);

    while (foundIndex !== -1) {
        // Remove the item by generating a new array without it
        array = [
            ...array.slice(0, foundIndex),
            ...array.slice(foundIndex + 1),
        ];

        // Bookkeeping
        fromIndex = foundIndex - 1;
        foundIndex = array.lastIndexOf(item, fromIndex)
    }

    // Return the new array
    return array;
}
6

Мне нравится эта версия соединения, $.inArray элемент по его значению с помощью $.inArray:

$(document).ready(function(){
    var arr = ["C#","Ruby","PHP","C","C++"];
    var itemtoRemove = "PHP";
    arr.splice($.inArray(itemtoRemove, arr),1);
});
  • 0
    Удаляет последний элемент, если найденный элемент не найден
  • 1
    да, правильно, вы должны знать, какой элемент вы хотите удалить, как в других примерах.
Показать ещё 2 комментария
6

Вы можете перебрать каждый array -item и splice его, если он существует в вашем array.

function destroy(arr, val) {
    for (var i = 0; i < arr.length; i++) if (arr[i] === val) arr.splice(i, 1);
    return arr;
}
  • 0
    destroy ([1,2,3,3,3,4,5], 3) возвращает [1,2,3,4,5]]. я не должен быть увеличен, когда массив склеен.
  • 0
    @RenzedeWaal это может сработать, если вы перебираете i назад, а не вперед. for (var i = arr.length; i--> 0;) [править] уже размещено здесь
5

Я только что создал polyfill для Array.prototype через Object.defineProperty чтобы удалить нужный элемент в массиве, не приводя к ошибкам при его повторном выполнении позже через for.. in..

if (!Array.prototype.remove) {
  // Object.definedProperty is used here to avoid problems when iterating with "for .. in .." in Arrays
  // https://stackoverflow.com/questions/948358/adding-custom-functions-into-array-prototype
  Object.defineProperty(Array.prototype, 'remove', {
    value: function () {
      if (this == null) {
        throw new TypeError('Array.prototype.remove called on null or undefined')
      }

      for (var i = 0; i < arguments.length; i++) {
        if (typeof arguments[i] === 'object') {
          if (Object.keys(arguments[i]).length > 1) {
            throw new Error('This method does not support more than one key:value pair per object on the arguments')
          }
          var keyToCompare = Object.keys(arguments[i])[0]

          for (var j = 0; j < this.length; j++) {
            if (this[j][keyToCompare] === arguments[i][keyToCompare]) {
              this.splice(j, 1)
              break
            }
          }
        } else {
          var index = this.indexOf(arguments[i])
          if (index !== -1) {
            this.splice(index, 1)
          }
        }
      }
      return this
    }
  })
} else {
  var errorMessage = 'DANGER ALERT! Array.prototype.remove has already been defined on this browser. '
  errorMessage += 'This may lead to unwanted results when remove() is executed.'
  console.log(errorMessage)
}

Удаление целочисленного значения

var a = [1, 2, 3]
a.remove(2)
a // Output => [1, 3]

Удаление строкового значения

var a = ['a', 'ab', 'abc']
a.remove('abc')
a // Output => ['a', 'ab']

Удаление логического значения

var a = [true, false, true]
a.remove(false)
a // Output => [true, true]

Также возможно удалить объект внутри массива с помощью этого метода Array.prototype.remove. Вам просто нужно указать key => value Object вы хотите удалить.

Удаление значения объекта

var a = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 3, b: 2}]
a.remove({a: 1})
a // Output => [{a: 2, b: 2}, {a: 3, b: 2}]
5

Я сделал довольно эффективное расширение базового массива JavaScript:

Array.prototype.drop = function(k) {
  var valueIndex = this.indexOf(k);
  while(valueIndex > -1) {
    this.removeAt(valueIndex);
    valueIndex = this.indexOf(k);
  }
};
  • 3
    Я прочитал, что вы не должны изменять объект, который вам не принадлежит
  • 0
    Также нет removeAt в стандарте ES. Я полагаю, это что-то только для IE? Это должно быть упомянуто в ответе.
5

По моему решению вы можете удалить один или несколько элементов в массиве благодаря чистому JavaScript. Нет необходимости в другой библиотеке JavaScript.

var myArray = [1,2,3,4,5]; // First array

var removeItem = function(array,value) {  // My clear function
    if(Array.isArray(value)) {  // For multi remove
        for(var i = array.length - 1; i >= 0; i--) {
            for(var j = value.length - 1; j >= 0; j--) {
                if(array[i] === value[j]) {
                    array.splice(i, 1);
                };
            }
        }
    }
    else { // For single remove
        for(var i = array.length - 1; i >= 0; i--) {
            if(array[i] === value) {
                array.splice(i, 1);
            }
        }
    }
}

removeItem(myArray,[1,4]); // myArray will be [2,3,5]
4

Еще один ответ, для меня, чем проще, тем лучше, и поскольку мы находимся в 2018 году (около 2019 года), я даю вам этот (около) один вкладыш, чтобы ответить на первоначальный вопрос:

Array.prototype.remove = function (value) { 
    return this.filter(f => f != value) 
}

Полезно то, что вы можете использовать его в выражении карри, например:

[1,2,3].remove(2).sort()

4

Удалите одно значение, используя свободное сравнение, без изменения исходного массива, ES6

/**
 * Removes one instance of 'value' from 'array', without mutating the original array. Uses loose comparison.
 * 
 * @param {Array} array Array to remove value from
 * @param {*} value Value to remove
 * @returns {Array} Array with 'value' removed
 */
export function arrayRemove(array, value) {
    for(let i=0; i<array.length; ++i) {
        if(array[i] == value) {
            let copy = [...array];
            copy.splice(i, 1);
            return copy;
        }
    }
    return array;
}
4

Хотя большинство приведенных выше ответов отвечают на вопрос, недостаточно ясно, почему метод slice() не использовался. Да, filter() соответствует критериям неизменности, но как насчет сделать следующий более короткий эквивалент:

const myArray = [1,2,3,4];

А теперь давайте скажем, что мы должны удалить второй элемент из массива, мы можем просто сделать: const newArray = myArray.slice(0,1).concat(myArray.slice(2,4)); //[1,3,4]

Этот способ удаления элемента из массива настоятельно рекомендуется сегодня в сообществе из-за его простой и неизменной природы. В общем, следует избегать методов, вызывающих мутацию. Например, вам рекомендуется заменить push() на concat() и splice() на slice()

4

Используйте jQuery.grep():

var y = [1, 2, 3, 9, 4]
var removeItem = 9;

y = jQuery.grep(y, function(value) {
  return value != removeItem;
});
console.log(y)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
  • 5
    ОП специально не сказал никаких рамок. Отсюда и отрицательный голос.
3

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

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

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

3

Очень наивная реализация будет выглядеть следующим образом:

Array.prototype.remove = function(data) {
    const dataIdx = this.indexOf(data)
    if(dataIdx >= 0) {
        this.splice(dataIdx ,1);
    }
    return this.length;
}

let a = [1,2,3];
// this will change arr a to [1, 3]
a.remove(2);

Я возвращаю длину массива из функции, чтобы соответствовать другим методам, таким как Array.prototype.push().

3

Для тех, кто хочет повторить метод, который будет возвращать новый массив, в котором удалены повторяющиеся числа или строки, он был составлен из существующих ответов:

function uniq(array) {
  var len = array.length;
  var dupFree = [];
  var tempObj = {};

  for (var i = 0; i < len; i++) {
    tempObj[array[i]] = 0;
  }

  console.log(tempObj);

  for (var i in tempObj) {
    var element = i;
    if (i.match(/\d/)) {
      element = Number(i);
    }
    dupFree.push(element);
  }

  return dupFree;
}
3

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

function removeElement(idx, arr) {
    // check the index value
    if (idx < 0 || idx >= arr.length) {
        return;
    }
    // shift the elements
    for (var i = idx; i > 0; --i) {
        arr[i] = arr[i - 1];
    }
    // remove the first element in array
    arr.shift();
}
3

Я сделал функцию

function pop(valuetoremove, myarray) {
var indexofmyvalue = myarray.indexOf(valuetoremove);
myarray.splice(indexofmyvalue, 1);
}

И использовал вот так.

pop(valuetoremove,myarray);

Ура!

  • 0
    Если вы собираетесь назвать его pop по крайней мере заставьте его делать то, что подразумевает имя метода!
3

Удалить последнее вхождение или все вхождения, или первое вхождение?

var array = [2, 5, 9, 5];

// Remove last occurrence (or all occurrences)
for (var i = array.length; i--;) {
  if (array[i] === 5) {
     array.splice(i, 1);
     break; // Remove this line to remove all occurrences
  }
}

или же

var array = [2, 5, 9, 5];

// Remove first occurrence
for (var i = 0; array.length; i++) {
  if (array[i] === 5) {
     array.splice(i, 1);
     break; // Do not remove this line
  }
}
3

Здесь есть много фантастических ответов, но для меня то, что сработало больше всего, это не полное удаление моего элемента из массива, а просто установка его значения на ноль. Это работает в большинстве случаев, которые у меня есть, и является хорошим решением, так как я буду использовать переменную позже и не хочу, чтобы она ушла, просто пока пусто. Кроме того, этот подход полностью совместим с браузерами.

array.key = null;
2

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

var filteredItems = this.items.filter(function (i) {
    return i !== item;
});

Чтобы придать приведенному фрагменту немного контекста:

self.thingWithItems = {
        items: [],
        removeItem: function (item) {
            var filteredItems = this.items.filter(function (i) {
                return i !== item;
            });

            this.items = filteredItems;
        }
    };

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

2

удалить элемент из последнего

arrName.pop();

удалить элемент из первого

arrName.shift();

удалить из середины

arrName.splice(starting index,number of element you wnt to delete);

Ex: arrName.splice(1,1);

удалить один элемент из последнего

arrName.splice(-1);

Удалить используя индексный номер массива

 delete arrName[1];
2

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

Если вы не заботитесь о заказе и не будете иметь одно и то же значение в контейнере более одного раза, используйте Set. Это будет намного быстрее и кратче.

var aSet = new Set();

aSet.add(1);
aSet.add(2);
aSet.add(3);

aSet.delete(2);
2
var array = [2, 5, 9];
array.splice(array.findIndex(x => x==5), 1);

Используя Array.findindex, мы можем уменьшить количество строк кода.

developer.mozilla.org

  • 0
    Лучше быть уверенным, что вы знаете, что элемент находится в массиве, иначе findindex возвращает -1 и, следовательно, удаляет 9.
2

Как жаль, что у вас есть массив целых чисел, а не объект, ключи которого являются строковыми эквивалентами этих чисел.

Я просмотрел многие из этих ответов, и, насколько я понимаю, все они используют "грубую силу". Я не исследовал каждый извинений, если это не так. Для небольшого массива это хорошо, но что если в нем есть тысячи целых чисел?

Поправьте меня, если я ошибаюсь, но разве мы не можем предположить, что в карте key => value, подобной объекту JS, можно предположить, что механизм поиска ключа является высоко разработанным и оптимизированным? (Примечание: если какой-нибудь супер-эксперт скажет мне, что это не так, я могу предложить вместо этого использовать класс ES6 Map, что, безусловно, будет).

Я просто предполагаю, что при определенных обстоятельствах лучшим решением может быть преобразование вашего массива в объект... проблема, конечно, в том, что у вас могут быть повторяющиеся целочисленные значения. Я предлагаю поместить их в ведра как часть "значения" записей key => value. (NB, если вы уверены, что у вас нет повторяющихся элементов массива, это может быть намного проще: значения "совпадают с" ключами, и просто зайдите в Object.values(...) чтобы вернуть ваш измененный массив).

Так что вы могли бы сделать:

const arr = [ 1, 2, 55, 3, 2, 4, 55 ];
const f =   function( acc, val, currIndex ){ 
    // not seen this val before: make bucket... NB although val typeof is 'number'
    // there is seamless equivalence between the object key (always string)
    // and this variable val 
    ! ( val in acc ) ? acc[ val ] = []: 0;
    // drop another array index in the bucket
    acc[ val ].push( currIndex );
    return acc; 
}
const myIntsMapObj = arr.reduce( f, {});

console.log( myIntsMapObj );

выход:

Object [ <1 empty slot>, Array1, Array[2], Array1, Array1, <5 empty slots>, 46 more… ]

тогда легко удалить все числа 55

delete myIntsMapObj[ 55 ]; // again, although keys are strings this works

Вам не нужно удалять их все: значения индекса помещаются в их сегменты в порядке появления, например (например):

myIntsMapObj[ 55 ].shift(); // and
myIntsMapObj[ 55 ].pop(); 

удалит первое и последнее вхождение соответственно. Вы можете легко посчитать частоту появления, заменить все 55 на 3, передав содержимое одного контейнера в другое и т.д.

... возврат вашего измененного массива int немного сложен: но каждый сегмент содержит индекс (в исходном массиве) значения, представленного ключом (string). Каждое из этих значений сегмента также уникально: таким образом, вы превращаете их в ключи в новом объекте, используя (действительное) целое число из "целочисленного строкового ключа" в качестве значения... затем сортируете ключи и переходите к Object.values(... )

Это звучит очень сложно и требует много времени... но, очевидно, все зависит от обстоятельств и желаемого использования. Насколько я понимаю, все версии и контексты JS работают только в одном потоке, и этот поток не "отпускается", поэтому при использовании метода "грубой силы" может возникнуть какая-то ужасная перегрузка: вызванная не столько операциями indexOf ops, но несколько повторных операций slice/splice.

добавление
Если вы уверены, что это слишком сложная разработка для вашего варианта использования, то, конечно, самый простой подход "грубой силы"

const arr = [ 1, 2, 3, 66, 8, 2, 3, 2 ];
const newArray = arr.filter( number => number !== 3 );
console.log( newArray )

(да, другие ответы обнаружили Array.prototype.filter...)

2

Следующий метод удалит все записи данного значения из массива без создания нового массива и только с одной итерацией, которая является сверхбыстрой. И это работает в древнем браузере Internet Explorer 5.5:

function removeFromArray(arr, removeValue) {
  for (var i = 0, k = 0, len = arr.length >>> 0; i < len; i++) {
    if (k > 0)
      arr[i - k] = arr[i];

    if (arr[i] === removeValue)
      k++;
  }

  for (; k--;)
    arr.pop();
}

var a = [0, 1, 0, 2, 0, 3];

document.getElementById('code').innerHTML =
  'Initial array [' + a.join(', ') + ']';
//Initial array [0, 1, 0, 2, 0, 3]

removeFromArray(a, 0);

document.getElementById('code').innerHTML +=
  '<br>Resulting array [' + a.join(', ') + ']';
//Resulting array [1, 2, 3]
<code id="code"></code>
  • 0
    Что означает этот код, я не мог понять.
  • 0
    @AnkurLoriya Этот код удаляет все 0 из данного массива
2

Удаление значения с помощью индекса и сплайсинга!

function removeArrValue(arr,value) {
    var index = arr.indexOf(value);
    if (index > -1) {
        arr.splice(index, 1);
    }
    return arr;
}
  • 14
    Ваши 2 последних комментария просто переписывают принятый ответ ... Пожалуйста, отвечайте на решенную проблему, только если у вас есть больше информации, чем предоставленный. Если нет, просто подтвердите принятый ответ.
2
var index,
    input = [1,2,3],
    indexToRemove = 1;
    integers = [];

for (index in input) {
    if (input.hasOwnProperty(index)) {
        if (index !== indexToRemove) {
            integers.push(result); 
        }
    }
}
input = integers;

Это решение будет принимать массив входных данных и будет искать во входных данных значение, которое нужно удалить. Это зациклит весь входной массив, и результатом будут целые числа второго массива, у которых был удален определенный индекс. Затем массив целых чисел копируется обратно во входной массив.

  • 1
    Это очень неэффективно, когда массив большой.
1

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

Синтаксис: array.splice(index, deleteCount, item1,....., itemX)

Здесь index обязателен, а остальные аргументы необязательны.

Например:

let arr = [1, 2, 3, 4, 5, 6];
arr.splice(2,1);
console.log(arr);
// [1, 2, 4, 5, 6]

Примечание. Метод Array.splice() можно использовать, если вы знаете индекс элемента, который хотите удалить. Но у нас может быть еще несколько случаев, как упомянуто below-

  1. Если вы хотите удалить только последний элемент, вы можете использовать Array.pop()

  2. Если вы хотите удалить только первый элемент, вы можете использовать Array.shift()

  3. Если вы знаете только один элемент, но не знаете его позицию (или индекс) и хотите удалить все соответствующие элементы с помощью метода Array.filter():

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

let newArr = arr.filter(function(val){
    return val !== 1;
});
//newArr => [2, 3, 4, 5]

ИЛИ с помощью метода splice() as-

let arr = [1, 11, 2, 11, 3, 4, 5, 11, 6, 11];
    for( let i = 0; i < arr.length-1; i++){
       if ( arr[i] === 11) {
         arr.splice(i, 1); 
       }
    }
    console.log(arr);
    // [1, 2, 3, 4, 5, 6]

ИЛИ предположим, что мы хотим удалить del из массива Arr:

let arr = [1, 2, 3, 4, 5, 6];
let del = 4;
if(arr.indexOf(4) >= 0) {
arr.splice(arr.indexOf(4), 1)
}

ИЛИ ЖЕ

let del = 4;
for(var i = arr.length - 1; i >= 0; i--) {
    if(arr[i] === del) {
       arr.splice(i, 1);
    }
}
  1. Если вы знаете только один элемент, но не знаете его позицию (или индекс) и хотите удалить только самый первый соответствующий элемент, используя метод splice():

let arr = [1, 11, 2, 11, 3, 4, 5, 11, 6, 11];

for( let i = 0; i < arr.length-1; i++){
   if ( arr[i] === 11) {
     arr.splice(i, 1);
     break;
   }
}
console.log(arr);
// [1, 11, 2, 11, 3, 4, 5, 11, 6, 11]
  • 0
    Примечание: Array.prototype.filter - это ECMAScript 5.1 (без IE8)
1

Определите метод с именем remove() для объектов массива, используя функцию прототипирования JavaScript.

Используйте метод splice(), чтобы выполнить ваше требование.

Пожалуйста, посмотрите на приведенный ниже код.

Array.prototype.remove = function(item) {
    // index will have -1 if item does not exist
    // else it will have the index of 1st item found in array
    var index = this.indexOf(item); 

    if (index > -1) {
        // splice() method is used to add/remove items(s) in array
        this.splice(index, 1); 
    }

    return index;
}


var arr = [ 11, 22, 67, 45, 61, 89, 34, 12, 7, 8, 3, -1, -4];

// Printing array
// [ 11, 22, 67, 45, 61, 89, 34, 12, 7, 8, 3, -1, -4];
console.log(arr)

// Removing 67 (getting its index i.e. 2)
console.log("Removing 67")
var index = arr.remove(67)

if (index > 0){
    console.log("Item 67 found at ", index)
} else {
    console.log("Item 67 does not exist in array")
}

// Printing updated array
// [ 11, 22, 45, 61, 89, 34, 12, 7, 8, 3, -1, -4];
console.log(arr)

// ............... Output ................................
// [ 11, 22, 67, 45, 61, 89, 34, 12, 7, 8, 3, -1, -4 ]
// Removing 67
// Item 67 found at  2
// [ 11, 22, 45, 61, 89, 34, 12, 7, 8, 3, -1, -4 ]

Примечание. Ниже приведен полный пример кода, выполняемого в REPL Node.js, в котором описано использование методов push(), pop(), shift(), unshift() и splice().

> // Defining an array
undefined
> var arr = [12, 45, 67, 89, 34, 12, 7, 8, 3, -1, -4, -11, 0, 56, 12, 34];
undefined
> // Getting length of array
undefined
> arr.length;
16
> // Adding 1 more item at the end i.e. pushing an item
undefined
> arr.push(55);
17
> arr
[ 12, 45, 67, 89, 34, 12, 7, 8, 3, -1, -4, -11, 0, 56, 12, 34, 55 ]
> // Popping item from array (i.e. from end)
undefined
> arr.pop()
55
> arr
[ 12, 45, 67, 89, 34, 12, 7, 8, 3, -1, -4, -11, 0, 56, 12, 34 ]
> // Remove item from beginning
undefined
> arr.shift()
12
> arr
[ 45, 67, 89, 34, 12, 7, 8, 3, -1, -4, -11, 0, 56, 12, 34 ]
> // Add item(s) at beginning
undefined
> arr.unshift(67); // Add 67 at begining of the array and return number of items in updated/new array
16
> arr
[ 67, 45, 67, 89, 34, 12, 7, 8, 3, -1, -4, -11, 0, 56, 12, 34 ]
> arr.unshift(11, 22); // Adding 2 more items at the beginning of array
18
> arr
[ 11, 22, 67, 45, 67, 89, 34, 12, 7, 8, 3, -1, -4, -11, 0, 56, 12, 34 ]
>
> // Define a method on array (temorarily) to remove an item and return the index of removed item; if it is found else return -1
undefined
> Array.prototype.remove = function(item) {
... var index = this.indexOf(item);
... if (index > -1) {
..... this.splice(index, 1); // splice() method is used to add/remove items in array
..... }
... return index;
... }
[Function]
>
> arr
[ 11, 22, 67, 45, 67, 89, 34, 12, 7, 8, 3, -1, -4, -11, 0, 56, 12, 34 ]
>
> arr.remove(45);   // Remove 45 (You will get the index of removed item)
3
> arr
[ 11, 22, 67, 67, 89, 34, 12, 7, 8, 3, -1, -4, -11, 0, 56, 12, 34 ]
>
> arr.remove(22)    // Remove 22
1
> arr
[ 11, 67, 67, 89, 34, 12, 7, 8, 3, -1, -4, -11, 0, 56, 12, 34 ]
> arr.remove(67)    // Remove 67
1
> arr
[ 11, 67, 89, 34, 12, 7, 8, 3, -1, -4, -11, 0, 56, 12, 34 ]
>
> arr.remove(89)    // Remove 89
2
> arr
[ 11, 67, 34, 12, 7, 8, 3, -1, -4, -11, 0, 56, 12, 34 ]
>
> arr.remove(100);  // 100 doesn't exist, remove() will return -1
-1
>

Благодарю.

1

Если вам требуется поддержка более старых версий Internet Explorer, я рекомендую использовать следующий полифилл (примечание: это не платформа). Это 100% обратно совместимая замена всех современных методов массива (JavaScript 1.8.5/ECMAScript 5 Array Extras), которая работает для Internet Explorer 6+, Firefox 1. 5+, Chrome, Safari и Opera.

https://github.com/plusdude/array-generics

  • 3
    Хотя эта ссылка может ответить на вопрос, лучше включить здесь основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными в случае изменения связанной страницы.
  • 1
    К сожалению, Интернет (и переполнение стека) заполнены наполовину реализованными, частично правильными версиями массивов ES5. В этом и заключается смысл ссылки на полифилл. Для действительно полного воспроизведения всех правильных поведений недостаточно обобщить «основные части». Вы должны также выполнить все граничные условия. Воспроизведение их содержимого в полном объеме выходит за рамки Stack Overflow. Переполнение стека не является GitHub.
0

Сращивание, фильтрация и удаление, чтобы удалить элемент из массива

Каждый массив имеет свой индекс, и это помогает удалить определенный элемент с их индексом.

Метод splice()

array.splice(index, 1); 1-й параметр - индекс, а второй - номер элемента, который вы

хотите удалить из этого индекса.

Так что для одного элемента мы используем 1.

Метод удаления

удалить массив [индекс]

Метод filter()

Если вы хотите удалить элемент, который повторяется в массиве, отфильтруйте массив.

removeAll = array.filter(e => e! = elem);

где elem - элемент, который вы хотите удалить из массива, а array - имя вашего массива.

0

Взятие прибыли по методу снижения следующим образом:

случай а) если вам нужно удалить элемент по индексу:

function remove(arr, index) {
  return arr.reduce((prev, x, i) => prev.concat(i !== index ? [x] : []), []);
}

случай б) если вам нужно удалить элемент по значению элемента (int):

function remove(arr, value) {
  return arr.reduce((prev, x, i) => prev.concat(x !== value ? [x] : []), []);
}

Таким образом, таким способом мы можем вернуть новый массив (это будет классный функциональный способ - намного лучше, чем использовать push или splice) с удаленным элементом.

0

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

array.splice(start [, deleteCount [, item1 [, item2 [,...]]]])

Начните

Индекс, с которого начинается изменение массива (с началом 0). Если он больше длины массива, фактический начальный индекс будет установлен равным длине массива. Если отрицательный, начнется, что много элементов с конца массива (с источником -1) и будет установлен в 0, если абсолютное значение больше, чем длина массива.

deleteCount Необязательно

Целое число, указывающее количество удаляемых старых элементов массива. Если deleteCount опущен или если его значение больше, чем array.length - start (то есть, если оно больше, чем число элементов, оставшихся в массиве, начиная с начала), то все элементы от начала до конца из массива будут удалены. Если deleteCount равен 0 или отрицателен, никакие элементы не удаляются. В этом случае вы должны указать хотя бы один новый элемент (см. Ниже).

item1, item2,... Необязательно

Элементы для добавления в массив, начиная с начального индекса. Если вы не укажете никаких элементов, splice() удалит только элементы из массива.

Для получения дополнительной информации, пожалуйста, пройдите:

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

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

arr.splice(0,1)

console.log(arr)

Выход [2, 3, 4, 5];

0

Вы можете использовать метод .splice() в массиве для удаления определенного элемента из массива.

Вы можете взять ссылку ниже. Https://www.hostingadvice.com/how-to/javascript-remove-element-array/

0
    Array.prototype.remove = function(start, end) {
        var n = this.slice((end || start) + 1 || this.length);
        return this.length = start < 0 ? this.length + start : start,
        this.push.apply(this, n)
    }

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

z=[0,1,2,3,4,5,6,7,8,9];

newlength=z.remove(2,6);

(8) [0, 1, 7, 8, 9]

z=[0,1,2,3,4,5,6,7,8,9];

newlength=z.remove(-4,-2);

(7) [0, 1, 2, 3, 4, 5, 9]

z=[0,1,2,3,4,5,6,7,8,9];

newlength=z.remove(3,-2);

(4) [0, 1, 2, 9]

0

Уже есть много ответов, но поскольку никто еще не сделал этого с одним вкладышем, я решил показать свой метод. Он использует тот факт, что функция string.split() удалит все указанные символы при создании массива. Вот пример:

var ary = [1,2,3,4,1234,10,4,5,7,3];
out = ary.join("-").split("-4-").join("-").split("-");
console.log(out);

В этом примере все 4 удаляются из массива. Однако важно отметить, что любой массив, содержащий символ "-", вызовет проблемы с этим примером. Короче говоря, это заставит функцию join ("-") неправильно соединить вашу строку. В такой ситуации все строки "-" в приведенном выше фрагменте могут быть заменены любой строкой, которая не будет использоваться в исходном массиве. Вот еще один пример:

var ary = [1,2,3,4,'-',1234,10,'-',4,5,7,3];
out = ary.join("!@#").split("!@#4!@#").join("!@#").split("!@#");
console.log(out);
  • 0
    Это будет работать только с массивом целых чисел ...
  • 1
    Вы видите, что есть строки во втором примере, который я предоставил? Я не уверен, что вы подразумеваете под этим? Единственная проблема заключается в том, что ваша строка содержит один из фрахтователей, используемых в разделении, как я уже упоминал в своем ответе.
Показать ещё 1 комментарий
0
Array.prototype.remove = function(x) {
    var y=this.slice(x+1);
    var z=[];
    for(i=0;i<=x-1;i++) {
        z[z.length] = this[i];
    }

    for(i=0;i<y.length;i++){
        z[z.length]=y[i];
    }

    return z;
}
-10
let array = [5,5,4,4,2,3,4]    
let newArray = array.join(',').replace('5','').split(',')

Этот пример работает, если вы хотите удалить один текущий элемент.

-10
var ar1 = [1,2,3,4,5,6,7,8,9]
var toBeRemoved = 2;
ar1.splice( (ar1.length -toBeRemoved) , toBeRemoved);
  • 0
    Он всегда удалит всего n элементов из последнего индекса массива. Если вам известен индекс удаляемого элемента, сделайте что-то вроде: пусть ar1 = [1,2,3,4,5,6,7,8,9]; ar1.splice (fromIndex, howManyToBeDelete); Для более подробной информации перейдите по ссылке: stackoverflow.com/a/54390552/8958729

Ещё вопросы

Сообщество Overcoder
Наверх
Меню