2013-03-08 4 views
119

У меня есть массив объектов, как так:Удалить элемент массива на основе свойства объекта

var myArray = [ 
    {field: 'id', operator: 'eq', value: id}, 
    {field: 'cStatus', operator: 'eq', value: cStatus}, 
    {field: 'money', operator: 'eq', value: money} 
]; 

Как удалить конкретный один, основанный на его свойства?

например. Как удалить объект массива с помощью «денег» как свойства поля?

ответ

177

Одним из возможных вариантов:

myArray = myArray.filter(function(obj) { 
    return obj.field !== 'money'; 
}); 

Пожалуйста, обратите внимание, что filter создает новый массив. Любые другие переменные, относящиеся к исходному массиву, не будут получать отфильтрованные данные, хотя вы обновите исходную переменную myArray с новой ссылкой. Используйте с осторожностью.

+5

Обратите внимание, что 'filter()' доступен только для Internet Explorer 9+ – jessegavin

+0

@jessegavin. Я должен был упомянуть, что есть много хороших библиотек * es5 shim *, которые имитируют функциональность (на всякий случай, если вы хотите поддерживать устаревшие браузеры). – jAndy

+2

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

52

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

for (var i = myArray.length - 1; i >= 0; --i) { 
    if (myArray[i].field == "money") { 
     myArray.splice(i,1); 
    } 
} 
+1

Что вы подразумеваете под живой природой массива? @Neit the Dark Absol – sisimh

+20

@sisimh он означает, что если вы перебираете вперед по массиву, используя его длину как часть логики итерации, и его длина изменяется, потому что у нее есть элементы, удаленные или добавленные, вы можете завершить работу с концом массива или не выполняет операцию для каждого элемента массива. Возвращение назад делает гораздо менее вероятным, поскольку оно работает с индексом статического 0, а не с движущейся длиной. – Klors

+1

спасибо за объяснение @Klors :) – sisimh

1

решение JANDY является, вероятно, лучше, но если вы не можете полагаться на фильтр вы могли бы сделать что-то вроде:

var myArray = [ 
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: "money"} 
]; 

myArray.remove_key = function(key){ 
    var i = 0, 
     keyval = null; 
    for(; i < this.length; i++){ 
     if(this[i].field == key){ 
      keyval = this.splice(i, 1); 
      break; 
     } 
    } 
    return keyval; 
} 
+1

Почему бы не Я могу полагаться на filter()? – imperium2335

+2

Потому что это часть JavaScript 1.6, которая не поддерживается IE8 и ниже или старше браузерами. –

3

Ниже приведен код, если вы не используете JQuery. Demo

var myArray = [ 
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: 'money'} 
]; 

alert(myArray.length); 

for(var i=0 ; i<myArray.length; i++) 
{ 
    if(myArray[i].value=='money') 
     myArray.splice(i); 
} 

alert(myArray.length); 

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

Underscore утилита ремень библиотека JavaScript, что обеспечивает большую функциональную поддержку программирования

+3

Это очень опасный пример для выхода в Интернет ... он работает с данными примера, но не с чем-либо еще. splice (i) означает, что он удалит все элементы в массиве, начиная с и после первого экземпляра, где значение - это деньги, которые не удовлетворяют требованию от op вообще. Если мы изменили на сплайсинг (i, 1), оно все равно было бы неверным, потому что оно не оценило бы следующий последовательный элемент (вам также нужно было бы уменьшить i). Поэтому вы должны обрабатывать операции удаления в массивах назад, чтобы удалить элемент не изменяет индексы следующих элементов для обработки –

7

Вот еще один вариант, с помощью JQuery Grep. Перейдите true в качестве третьего параметра для обеспечения того, что grep удаляет элементы, соответствующие вашей функции.

users = $.grep(users, function(el, idx) {return el.field == "money"}, true) 

Если вы уже используете JQuery, то нет прокладок не требуется, который может быть полезным в отличие от использования Array.filter.

4

Вы можете использовать lodash's findIndex, чтобы получить индекс конкретного элемента, а затем сплайсировать его.

myArray.splice(_.findIndex(myArray, function(item) { 
    return item.value === 'money'; 
}), 1); 
+0

Что такое массив - древовидная структура? – forgottofly

+0

@forgottofly древовидная структура? Я думаю, что 'myArray' здесь представляет собой массив объектов. – Sridhar

+1

Что делать, если массив является древовидной структурой var beforeDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"} , {"id": 23, "name": "changed test 23"}]}], и я хочу удалить id: 23 – forgottofly

2
var myArray = [ 
    {field: 'id', operator: 'eq', value: id}, 
    {field: 'cStatus', operator: 'eq', value: cStatus}, 
    {field: 'money', operator: 'eq', value: money} 
]; 
console.log(myArray.length); //3 
myArray = $.grep(myArray, function(element, index){return element.field == "money"}, true); 
console.log(myArray.length); //2 

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

+1

Ваше решение кристально чистое. благодаря –

Смежные вопросы