【问题标题】:Remove element from array of objects javascript从对象数组中删除元素javascript
【发布时间】:2017-03-21 23:30:09
【问题描述】:

我有以下对象数组。

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

其中一些记录是对立的。第一个元素和第四个元素具有相同的 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;
        }
    })
})

有什么优雅的方法可以达到预期的输出吗?

【问题讨论】:

    标签: javascript jquery angularjs arrays


    【解决方案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)

    【讨论】:

      【解决方案2】:

      使用http://underscorejs.org/#where 并这样做:

      var newArrOfObj=_.where(arrOfObj, {disabled:true});
      

      【讨论】:

        【解决方案3】:

        您可以使用多个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)

        【讨论】:

          【解决方案4】:

          这是函数式编程风格的 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 数组转换回预期的格式。

          【讨论】:

            【解决方案5】:

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

            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; }

            【讨论】:

              猜你喜欢
              • 2016-05-12
              • 2020-01-31
              • 2011-03-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-12-26
              • 2019-10-21
              相关资源
              最近更新 更多