Как удалить элемент из массива по значению?

есть ли способ удалить элемент из массива JavaScript?

дан массив:

var ary = ['three', 'seven', 'eleven'];

Я хотел бы сделать что-то вроде:

removeItem('seven', ary);

Я проверил splice() но это удаляет только номер позиции, в то время как мне нужно что-то удалить элемент по его значению.

30 ответов


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

Array.prototype.remove = function() {
    var what, a = arguments, L = a.length, ax;
    while (L && this.length) {
        what = a[--L];
        while ((ax = this.indexOf(what)) !== -1) {
            this.splice(ax, 1);
        }
    }
    return this;
};

var ary = ['three', 'seven', 'eleven'];

ary.remove('seven');

/*  returned value: (Array)
three,eleven
*/

чтобы сделать его глобальным-

function removeA(arr) {
    var what, a = arguments, L = a.length, ax;
    while (L > 1 && arr.length) {
        what = a[--L];
        while ((ax= arr.indexOf(what)) !== -1) {
            arr.splice(ax, 1);
        }
    }
    return arr;
}
var ary = ['three', 'seven', 'eleven'];
removeA(ary, 'seven');


/*  returned value: (Array)
three,eleven
*/

и заботиться о IE8 и ниже-

if(!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(what, i) {
        i = i || 0;
        var L = this.length;
        while (i < L) {
            if(this[i] === what) return i;
            ++i;
        }
        return -1;
    };
}

можно использовать indexOf метод такой:

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

Примечание: вам нужно будет проколоть его для IE8 и ниже

var array = [1,2,3,4]
var item = 3

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

console.log(array)

один лайнер сделает это,

var ary = ['three', 'seven', 'eleven'];

// Remove item 'seven' from array
var filteredAry = ary.filter(function(e) { return e !== 'seven' })
//=> ["three", "eleven"]

// In ECMA6 (arrow function syntax):
var filteredAry = ary.filter(e => e !== 'seven')

это использует фильтр функция в JS. Он поддерживается в IE9 и выше.

что он делает (из ссылки doc)

filter () вызывает предоставленную функцию обратного вызова один раз для каждого элемента в массиве и создает новый массив всех значений, для которых обратный вызов возвращает значение, совпадающее с true. обратный вызов вызывается только для индексов массива, которым присвоены значения; это не вызывается для индексов, которые были удалены или которым никогда не назначались значения. Элементы массива, которые не проходят тест обратного вызова, просто пропускаются и не включаются в новый массив.

Итак, в основном, это то же самое, что и все остальные for (var key in ary) { ... } решения, за исключением того, что for in конструкция поддерживается с IE6.

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


можно использовать подчеркивания.js. Это действительно упрощает дело.

например, вот это:

var result = _.without(['three','seven','eleven'], 'seven');

и result будет ['three','eleven'].

в вашем случае код, который вы должны написать:

ary = _.without(ary, 'seven')

Это уменьшает код, который вы пишете.


проверить таким образом:

for(var i in array){
    if(array[i]=='seven'){
        array.splice(i,1);
        break;
    }
}

и в функции:

function removeItem(array, item){
    for(var i in array){
        if(array[i]==item){
            array.splice(i,1);
            break;
        }
    }
}

removeItem(array, 'seven');

вот версия, которая использует jQuery функция inArray:

var index = $.inArray(item, array);
if (index != -1) {
    array.splice(index, 1);
}

var index = array.indexOf('item');

if(index!=-1){

   array.splice(index, 1);
}

вы можете сделать это двумя способами:

var arr = ["1","2","3","4"] // we wanna delete number "3"

первый:

arr.indexOf('3') !== -1 && arr.splice(arr.indexOf('3'), 1)

второй (ES6):

arr = arr.filter(e => e !== '3')

вам нужен фильтр

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

Это позволит вам сделать следующее:

var ary = ['three', 'seven', 'eleven'];
var aryWithoutSeven = ary.filter(function(value) { return value != 'seven' });
console.log(aryWithoutSeven); // returns ['three', 'eleven']

Это также было отмечено в этом потоке где-то еще:https://stackoverflow.com/a/20827100/293492


видя, что нет красивого, вот простая и многоразовая функция ES6.

const removeArrayItem = (arr, itemToRemove) => {
  return arr.filter(item => item !== itemToRemove)
}

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

const items = ['orange', 'purple', 'orange', 'brown', 'red', 'orange']
removeArrayItem(items, 'orange')

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

/**
 * @param {Array} array the original array with all items
 * @param {any} item the time you want to remove
 * @returns {Array} a new Array without the item
 */
var removeItemFromArray = function(array, item){
  /* assign a empty array */
  var tmp = [];
  /* loop over all array items */
  for(var index in array){
    if(array[index] !== item){
      /* push to temporary array if not like item */
      tmp.push(array[index]);
    }
  }
  /* return the temporary array */
  return tmp;
}

Если у вас есть уникальные значения в массиве и заказ не имеет значения, вы можете использовать Set, и удалить:

var mySet = new Set(['foo']);
mySet.delete('foo'); // Returns true.  Successfully removed.
mySet.has('foo');    // Returns false. The "foo" element is no longer present.

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

while ($.inArray(item, array) > -1) {
    array.splice( $.inArray(item, array), 1 );
}

я использовал jQuery для тяжелого подъема, но вы получите идею, если хотите стать родным.


indexOf является опцией, но ее реализация в основном ищет весь массив для значения, поэтому время выполнения растет с размером массива. (так что в каждом браузере я думаю, я только проверил Firefox).

у меня нет IE6, чтобы проверить, но я бы назвал это безопасной ставкой, что вы можете проверить по крайней мере миллион элементов массива в секунду таким образом почти на любой клиентской машине. Если [размер массива]*[поиск в секунду] может превышать миллион, вы должны рассмотреть другое реализация.

в основном вы можете использовать объект для создания индекса для вашего массива, например:

var index={'three':0, 'seven':1, 'eleven':2};

любая разумная среда JavaScript создаст индекс для поиска таких объектов, чтобы вы могли быстро перевести ключ в значение, независимо от того, сколько свойств имеет объект.

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


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

arr = arr.filter(value => value !== 'seven');

или, может быть, вы хотите использовать vanilla JS

arr = arr.filter(function(value) { return value !== 'seven' });

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

var deleteMe = function( arr, me ){
   var i = arr.length;
   while( i-- ) if(arr[i] === me ) arr.splice(i,1);
}

var arr = ["orange","red","black", "orange", "white" , "orange" ];

deleteMe( arr , "orange");

arr теперь ["красный", "черный", "белый"]


путь ES6.

let commentsWithoutDeletedArray = commentsArray.filter( (comment) => !(comment.Id === commentId));

удаление без разрушения:

function removeArrayValue(array, value)
{
    var thisArray = array.slice(0); // copy the array so method is non-destructive

    var idx = thisArray.indexOf(value); // initialise idx

    while(idx != -1)
    {
        thisArray.splice(idx, 1); // chop out element at idx

        idx = thisArray.indexOf(value); // look for next ocurrence of 'value'
    }

    return thisArray;
}

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

> Array.prototype.remove=function(v){
...     delete this[this.indexOf(v)]
... };
[Function]
> var myarray=["3","24","55","2"];
undefined
> myarray.remove("55");
undefined
> myarray
[ '3', '24', , '2' ]

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

function cleanArrayOfSpecificTerms(array,unwantedTermsArray) {
  $.each(unwantedTermsArray, function( index, value ) {
    var index = array.indexOf(value);
    if (index > -1) {
      array.splice(index, 1);        
    }
  });
  return array;
}

для использования выполните следующие действия:

var notInclude = ['Not','No','First','Last','Prior','Next', 'dogs','cats'];
var splitTerms = ["call", "log", "dogs", "cats", "topic", "change", "pricing"];

cleanArrayOfSpecificTerms(splitTerms,notInclude)

function removeFrmArr(array, element) {
  return array.filter(e => e !== element);
};
var exampleArray = [1,2,3,4,5];
removeFrmArr(a, 3);
// return value like this
//[1, 2, 4, 5]

можно использовать without или pull С Лодашь:

const _ = require('lodash');
_.without([1, 2, 3, 2], 2); // -> [1, 3]

let arr = [5, 15, 25, 30, 35];
console.log(arr); //result [5, 15, 25, 30, 35]
let index = arr.indexOf(30);

if (index > -1) {
   arr.splice(index, 1);
}
console.log(arr); //result [5, 15, 25, 35]

var remove = function(array, value) {
    var index = null;

    while ((index = array.indexOf(value)) !== -1)
        array.splice(index, 1);

    return array;
};

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

var newArray = referenceArray;

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

function newArrRemoveItem(array, item, newArray){
    for(var i = 0; i < array.length; i++) {
        if(array[i]!=item){
            newArray.push(array[i]);
        }
    }
}

тогда я использую его так в другой функции:

var vesselID = record.get('VesselID');
var otherVessels = new Array();
newArrRemoveItem(vesselArr,vesselID,otherVessels);

Теперь vesselArr остается нетронутым, в то время как каждый раз, когда я выполняю вышеуказанный код, массив otherVessels включает все, кроме последнего элемента vesselID.


вариант CoffeeScript+jQuery:

arrayRemoveItemByValue = (arr,value) ->
  r=$.inArray(value, arr)
  unless r==-1
    arr.splice(r,1)
  # return
  arr

console.log arrayRemoveItemByValue(['2','1','3'],'3')

Он удаляет только один, а не все.


//This function allows remove even array from array
var removeFromArr = function(arr, elem) { 
    var i, len = arr.length, new_arr = [],
    sort_fn = function (a, b) { return a - b; };
    for (i = 0; i < len; i += 1) {
        if (typeof elem === 'object' && typeof arr[i] === 'object') {
            if (arr[i].toString() === elem.toString()) {
                continue;
            } else {                    
                if (arr[i].sort(sort_fn).toString() === elem.sort(sort_fn).toString()) {
                    continue;
                }
            }
        }
        if (arr[i] !== elem) {
            new_arr.push(arr[i]);
        }
    }
    return new_arr;
}

пример использования

var arr = [1, '2', [1 , 1] , 'abc', 1, '1', 1];
removeFromArr(arr, 1);
//["2", [1, 1], "abc", "1"]

var arr = [[1, 2] , 2, 'a', [2, 1], [1, 1, 2]];
removeFromArr(arr, [1,2]);
//[2, "a", [1, 1, 2]]

другой вариант:

if (!Array.prototype.removeArr) {
    Array.prototype.removeArr = function(arr) {
        if(!Array.isArray(arr)) arr=[arr];//let's be nice to people who put a non-array value here.. that could be me!
        var that = this;
        if(arr.length){
            var i=0;
            while(i<that.length){
                if(arr.indexOf(that[i])>-1){
                    that.splice(i,1);
                }else i++;
            }
        }
        return that;
    }
}

это indexOf () внутри цикла снова, но в предположении, что массив для удаления мал относительно массива, который нужно очистить; каждое удаление сокращает цикл while.


//отредактированы спасибо MarcoCI советы

попробуйте это:

function wantDelete(item, arr){
  for (var i=0;i<arr.length;i++){
    if (arr[i]==item){
      arr.splice(i,1); //this delete from the "i" index in the array to the "1" length
      break;
    }
  }  
}
var goodGuys=wantDelete('bush', ['obama', 'bush', 'clinton']); //['obama', 'clinton']

надеюсь, что это поможет вам


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

 var ary = ['three', 'seven', 'eleven'];
 var index = ary.indexOf(item);//item: the value which you want to remove

 //Method 1
 ary.splice(index,1);

 //Method 2
 delete ary[index]; //in this method the deleted element will be undefined