2016-11-08 5 views
2

У меня есть следующий массив объектов.Удалить элемент из массива объектов javascript

[{"rId":24,"gId":40,"sId":20,"disabled":false}, 
{"rId":24,"gId":40,"sId":19,"disabled":false}, 
{"rId":24,"gId":40,"sId":50,"disabled":false}, 
{"rId":24,"gId":40,"sId":20,"disabled":true}, 
{"rId":24,"gId":40,"sId":19,"disabled":true}, 
{"rId":24,"gId":40,"sId":50,"disabled":true}, 
{"rId":24,"gId":39,"sId":18,"disabled":false}] 

В каких-то записях есть антитеза ex. 1-й элемент и 4-й, который имеет одинаковый флаг rId, gId и sId, но отключен, противоположный. Я хочу исключить все такие записи.

Мой ожидаемый массив {"rId":24,"gId":39,"sId":18,"disabled":false} (удалить все записи антитезы)

Я попытался следующий код, но он дает мне неправильный вывод.

arrOfObj=[{"rId":24,"gId":40,"sId":20,"disabled":false}, 
{"rId":24,"gId":40,"sId":19,"disabled":false}, 
{"rId":24,"gId":40,"sId":50,"disabled":false}, 
{"rId":24,"gId":40,"sId":20,"disabled":true}, 
{"rId":24,"gId":40,"sId":19,"disabled":true}, 
{"rId":24,"gId":40,"sId":50,"disabled":true}, 
{"rId":24,"gId":39,"sId":18,"disabled":false}] 


$.each(arrOfObj,function (index1,firstObj) { 
    $.each(arrOfObj,function (index2,secondObj) { 
     if(index1>= index2){ 
      return true; 
     } 
     var areObjAntithesis=firstObj.rId===secondObj.rId && firstObj.gId===secondObj.gId 
      && firstObj.sId===secondObj.sId && firstObj.disabled!==secondObj.disabled; 

     if(areObjAntithesis){ 
      arrOfObj.splice(index1,1); 
      arrOfObj.splice(index2,1) 
      return false; 
     } 
    }) 
}) 

Есть ли элегантный способ достижения ожидаемого результата?

ответ

1

Вы могли бы сделать это с map() и filter()

var data = [{"rId":24,"gId":40,"sId":20,"disabled":false}, 
 
{"rId":24,"gId":40,"sId":19,"disabled":false}, 
 
{"rId":24,"gId":40,"sId":50,"disabled":false}, 
 
{"rId":24,"gId":40,"sId":20,"disabled":true}, 
 
{"rId":24,"gId":40,"sId":19,"disabled":true}, 
 
{"rId":24,"gId":40,"sId":50,"disabled":true}, 
 
{"rId":24,"gId":39,"sId":18,"disabled":false}] 
 
    
 
var ar = data.map(function(e) { 
 
    return e.rId + '|' + e.gId + '|' + e.sId; 
 
}); 
 
    
 
var result = data.filter(function(e) { 
 
    var key = e.rId + '|' + e.gId + '|' + e.sId; 
 
    return ar.indexOf(key) == ar.lastIndexOf(key); 
 
}); 
 

 
console.log(result)

0

Вы можете использовать несколько array.filter и проверить подсчет и только возвращение элементы, которые имеют более 1 значения и если значения одинаковы или имеют только одно значение

var data = [{"rId":24,"gId":40,"sId":20,"disabled":false}, 
 
{"rId":24,"gId":40,"sId":19,"disabled":false}, 
 
{"rId":24,"gId":40,"sId":50,"disabled":false}, 
 
{"rId":24,"gId":40,"sId":20,"disabled":true}, 
 
{"rId":24,"gId":40,"sId":19,"disabled":true}, 
 
{"rId":24,"gId":40,"sId":50,"disabled":true}, 
 
{"rId":24,"gId":39,"sId":18,"disabled":false}] 
 

 
var result = data.filter(function(outer){ 
 
    var disablesValues = [] 
 
    
 
    var _r = data.filter(function(inner){ 
 
    if(inner.gId === outer.gId && inner.sId === outer.sId){ 
 
     if(disablesValues.indexOf(inner.disabled) < 0) 
 
     disablesValues.push(inner.disabled); 
 
     return true; 
 
    } 
 
    }); 
 
    
 
    return _r.length === 1 || disablesValues.length === 1 
 
}); 
 

 
console.log(result)

0

Вы могли бы две петли, одна для сбора и один для фильтрации массива.

var data = [{ "rId": 24, "gId": 40, "sId": 20, "disabled": false }, { "rId": 24, "gId": 40, "sId": 19, "disabled": false }, { "rId": 24, "gId": 40, "sId": 50, "disabled": false }, { "rId": 24, "gId": 40, "sId": 20, "disabled": true }, { "rId": 24, "gId": 40, "sId": 19, "disabled": true }, { "rId": 24, "gId": 40, "sId": 50, "disabled": true }, { "rId": 24, "gId": 39, "sId": 18, "disabled": false }], 
 
    hash = Object.create(null), 
 
    getKey = function (o) { return ["rId", "gId", "sId"].map(function (k) { return o[k]; }).join('|'); }, 
 
    result; 
 

 
data.forEach(function (a) { 
 
    var key = getKey(a); 
 
    hash[key] = (hash[key] || 0) + (a.disabled || -1); 
 
}); 
 

 
result = data.filter(function (a) { 
 
    return hash[getKey(a)]; 
 
}); 
 

 
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

ES6 с Array#find

var data = [{ "rId": 24, "gId": 40, "sId": 20, "disabled": false }, { "rId": 24, "gId": 40, "sId": 19, "disabled": false }, { "rId": 24, "gId": 40, "sId": 50, "disabled": false }, { "rId": 24, "gId": 40, "sId": 20, "disabled": true }, { "rId": 24, "gId": 40, "sId": 19, "disabled": true }, { "rId": 24, "gId": 40, "sId": 50, "disabled": true }, { "rId": 24, "gId": 39, "sId": 18, "disabled": false }], 
 
    result = data.filter(a => 
 
     !data.find(b => ["rId", "gId", "sId"].every(k => 
 
      a[k] === b[k] 
 
     ) && a.disabled !== b.disabled)); 
 

 
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

0

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

function eliminateOpposites(arr) { 
 
    return [...arr 
 
     .map(o => ({ o, k: JSON.stringify({ rId:o.rId, gId:o.gId, sId:o.sId }) })) 
 
     .reduce((acc, o) => acc.set(o.k, (acc.get(o.k) || 0)+ (+o.o.disabled || -1)), 
 
          new Map())] 
 
     .filter(([k, balance]) => balance) 
 
     .map(([k, balance]) => Object.assign(JSON.parse(k), {disabled: balance>0})); 
 
} 
 

 
// Sample data 
 
var arrOfObj=[ 
 
{"rId":24,"gId":40,"sId":20,"disabled":false}, 
 
{"rId":24,"gId":40,"sId":19,"disabled":false}, 
 
{"rId":24,"gId":40,"sId":50,"disabled":false}, 
 
{"rId":24,"gId":40,"sId":20,"disabled":true}, 
 
{"rId":24,"gId":40,"sId":19,"disabled":true}, 
 
{"rId":24,"gId":40,"sId":50,"disabled":true}, 
 
{"rId":24,"gId":39,"sId":18,"disabled":false}] 
 
    
 
console.log(eliminateOpposites(arrOfObj));

Это делает использование хэширования, что приводит к О (п) алгоритма вместо O (N²), что соответствует indexOf -уровневым решениям.

JSON.stringify и JSON.parse используются для составления и разложения значений составных ключей. Строковая версия служит ключом в Map, в котором каждая запись регистрирует количество отключенных или активированных вхождений одного и того же ключа.Вызов .filter() выдает случаи, когда количество отключенных и включенных вхождений одинаково (может быть 2 против 2), а окончательный .map() возвращает массив kay/value обратно в ожидаемый формат.

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