从javascript对象数组中删除元素

时间:2016-11-08 11:02:54

标签: javascript jquery angularjs arrays

我有以下对象数组。

[{"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;
        }
    })
})

有没有优雅的方法来实现预期的产出?

5 个答案:

答案 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)

你可以有两个循环,一个用于收集,一个用于过滤数组。

&#13;
&#13;
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;
&#13;
&#13;

ES6与Array#find

&#13;
&#13;
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;
&#13;
&#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.stringifyJSON.parse用于组合和分解复合键值。字符串版本用作Map中的密钥,其中每个条目记录相同密钥的已禁用与已启用事件的计数。 .filter()调用启动了禁用和启用事件计数相同的情况(可能是2对2),最后.map()将kay / value数组转换回预期格式。