it-roy-ru.com

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

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

Учитывая массив:

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

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

removeItem('seven', ary);

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

717
MacMac

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

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

Вы можете использовать метод 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)

1270
SLaks

Однострочник сделает это,

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

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

Что он делает (из ссылки на документацию)

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

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

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

302
John Williams

Вы можете использовать underscore.js . Это действительно делает вещи простыми.

Например, с этим:

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

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

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

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

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

127
vatsal

Проверьте это так:

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');
49
gadlol

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

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

if(index!=-1){

   array.splice(index, 1);
}
27
Kld

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

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')
26
AmerllicA

Что вы после того, как фильтр

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

15
Lotus

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

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

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

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

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

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

ES6 кстати.

const commentsWithoutDeletedArray = commentsArray.filter(comment => comment.Id !== commentId);
7
Oliver Dixon

Просто

var ary = ['three', 'seven', 'eleven'];
var index = ary.indexOf('seven'); // get index if value found otherwise -1

 if (index > -1) { //if found
   ary.splice(index, 1);
 }
7
Matee Gojra

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

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

Я использовал jQuery для тяжелой работы, но у вас есть идея, если вы хотите перейти на родной язык.

7
Jason

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

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

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

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

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

/**
 * @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;
}
6
mtizziani

Вы можете добиться этого, используя функцию Lodash_.remove .

var array = ['three', 'seven', 'eleven'];
var evens = _.remove(array, function(e) {
  return e !== 'seven';
});

console.log(evens);
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

4
Yi-Ting Liu

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

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

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

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

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

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

4
aaaaaaaaaaaa

Во всех уникальных значениях вы можете:

a = new Set([1,2,3,4,5]) // a = Set(5) {1, 2, 3, 4, 5}
a.delete(3) // a = Set(5) {1, 2, 4, 5} 
[...a] // [1, 2, 4, 5]
3
Eugene Lyzo

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

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

арр сейчас ["красный", "черный", "белый"]

3
chaoticflow

Вы можете использовать without или pull из Lodash :

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

Неразрушающее удаление:

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;
}
2
Randhir Rawatlal
function removeFrmArr(array, element) {
  return array.filter(e => e !== element);
};
var exampleArray = [1,2,3,4,5];
removeFrmArr(exampleArray, 3);
// return value like this
//[1, 2, 4, 5]
2
Subhojit Mondal

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

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)
1
maudulus
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]
1
Asif vora

Пожалуйста, не используйте вариант с 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' ]
1
Ilya Sher
var remove = function(array, value) {
    var index = null;

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

    return array;
};
0
Alexander Abashkin

// отредактировал спасибо 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']

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

0
julian
//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]]
0
yesnik

Я попытался использовать метод функции из 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.

0
Robert

Еще один вариант:

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.

0
dkloke

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

 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
0
Srikrushna Pal

Вариант 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')

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

0
Igor Teterin

Самое простое решение:

array.filter(valueForRemove => array.includes(valueForRemove));
0
Jackkobec

Вы можете использовать функцию тяги lodash

var ary = ['three', 'seven', 'eleven'];
_.pull(ary, 'seven'); // ['three', 'eleven']
console.log(ary)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.6.1/lodash.js"></script>

0
Parth Raval