我有以下对象数组。
[{"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}]
其中一些记录是对立的。第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;
}
})
})
有没有优雅的方法来实现预期的产出?
答案 0 :(得分: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)
答案 1 :(得分:0)
使用http://underscorejs.org/#where并执行以下操作:
var newArrOfObj=_.where(arrOfObj, {disabled:true});
答案 2 :(得分: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)
答案 3 :(得分: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);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
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);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
答案 4 :(得分: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.stringify
和JSON.parse
用于组合和分解复合键值。字符串版本用作Map
中的密钥,其中每个条目记录相同密钥的已禁用与已启用事件的计数。 .filter()
调用启动了禁用和启用事件计数相同的情况(可能是2对2),最后.map()
将kay / value数组转换回预期格式。