2016-11-08 93 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。 1st元素和4th元素具有相同的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)算法代替O(N²),这是indexOf风格的解决方案。

JSON.stringifyJSON.parse用于组合和分解组合键值。字符串版本在Map中用作密钥,其中每个条目记录相同密钥的禁用与启用事件的计数。.filter()调用将启用禁用和启用事件计数相同(可能为2对2)的情况,并且最终.map()将kay/value数组变回预期格式。