Lodash过滤掉对象数组

时间:2019-09-26 16:33:46

标签: javascript arrays ecmascript-6 lodash

我正在尝试使用lodash过滤掉嵌套的对象数组,这很简单,但我希望避免多次调用。

我正在使用一个lodash调用/函数创建2个对象数组。要查找对象属性“ $ isMultiAccount”(如果存在),请将整个对象放入一个结果集中,如果没有,则将其放入另一个规则集中。

当前,我首先使用Lodash“具有并过滤”和其他“!具有”来执行此操作,这意味着同一对象被循环了两次,因为对象相对较大,这会导致速度瓶颈

https://repl.it/repls/HomelyExpensiveTruetype

const item = {
  "domains": [
    {
      "id": "dm11022",
      "information":{
        "description": "Customer",
        "owner": {
          "primary":{
            "name": "James",
            "phone": "NA"
          },
          "others": [
            {
              "$isMultiAccount": "./Yes"
            }
          ]
        }
      }
    },
    {
      "id": "dm12022",
      "information":{
        "description": "Customer",
        "owner": {
          "primary":{
            "name": "James",
            "phone": "NA"
          },
          "others": [
            {
              "$isMultiAccount": "./No"
            }
          ]
        }
      }
    },
    {
      "id": "dm12022",
      "information":{
        "description": "Customer",
        "owner": {
          "primary":{
            "name": "James",
            "phone": "NA"
          },
          "others": [
            {
              "conf": {
                  "isVpnBased":{
                    "accountType": "Primary"
                  }
              }
            }
          ]
        }
      }
    }


  ]
}
/*
Expected result
  output1 = [
        {
      "id": "dm11022",
      "information":{
        "description": "Customer",
        "owner": {
          "primary":{
            "name": "James",
            "phone": "NA"
          },
          "others": [
            {
              "$isMultiAccount": "./Yes"
            }
          ]
        }
      }
    },
    {
      "id": "dm12022",
      "information":{
        "description": "Customer",
        "owner": {
          "primary":{
            "name": "James",
            "phone": "NA"
          },
          "others": [
            {
              "$isMultiAccount": "./No"
            }
          ]
        }
      }
    }
  ]

// $isMultiAccount account do not exist in this object
 output2 = [
       {
      "id": "dm12022",
      "information":{
        "description": "Customer",
        "owner": {
          "primary":{
            "name": "James",
            "phone": "NA"
          },
          "others": [
            {
              "conf": {
                  "isVpnBased":{
                    "accountType": "Primary"
                  }
              }
            }
          ]
        }
      }
    }
 ]


 */

3 个答案:

答案 0 :(得分:1)

const item = {
"domains": [
{
  "id": "dm11022",
  "information":{
    "description": "Customer",
    "owner": {
      "primary":{
        "name": "James",
        "phone": "NA"
      },
      "others": [
        {
          "$isMultiAccount": "./Yes"
        }
      ]
    }
  }
},
{
  "id": "dm12022",
  "information":{
    "description": "Customer",
    "owner": {
      "primary":{
        "name": "James",
        "phone": "NA"
      },
      "others": [
        {
          "$isMultiAccount": "./No"
        }
      ]
    }
  }
},
{
  "id": "dm12022",
  "information":{
    "description": "Customer",
    "owner": {
      "primary":{
        "name": "James",
        "phone": "NA"
      },
      "others": [
        {
          "conf": {
              "isVpnBased":{
                "accountType": "Primary"
              }
          }
        }
      ]
    }
  }
}
]
}
const [areMulti, areNotMulti] = _.reduce(item.domains, (current, next) => {
  return _.has(next, ‘information.owner.others.$isMultiAccount’)
    ? [current[0].concat(next), current[1]]
    : [current[0], current[1].concat(next)];
}, [[], []]);
console.log(areMulti);
console.log(areNotMulti);

答案 1 :(得分:0)

由于item.domains.information.owner.others是一个数组,因此您需要按以下方法处理:

let multi = []; 
let notMulti = [];
_.each(item.domains, function (obj) {
   if (obj.information.owner.others.length && _.has(obj.information.owner.others[0], '$isMultiAccount'))
      multi.push(obj);
   else
      notMulti.push(obj);
});
console.log(multi);
console.log(notMulti);

答案 2 :(得分:0)

不幸的是,您必须遍历domains数组以及owner.others数组上的屁股,才能确定具有特定键的对象是否位于其中。

因此该算法具有O(n*m)复杂度。

如果您要求使用lodash函数,似乎您正在寻找partition方法

如文档所述:

  

创建一个分为两组的元素数组,其中第一个包含谓词返回true的元素,第二个包含谓词返回falsey的元素。谓词使用一个参数调用:(值)。

因此它将是:

_.partition(
  item.domains,
  e => _.some(
    _.get(e, 'information.owner.others'),
    el => _.has(el,"$isMultiAccount")
  )
);

当心-一些黑客可用!

但是,如果您100%确定要查找的元素将始终位于特定索引处(例如,应该始终作为第一个元素-因此索引为0),则可以将算法限制为具有线性复杂度O(n),因为只有domains数组的大小会影响性能。

假设固定数组索引= 0的骇客解决方案:

_.partition(
  item.domains,
  e => _.has(e, 'information.owner.others.0.$isMultiAccount')
);

注意 使用lodash使代码更易于阅读,但无论如何当然会产生一些性能开销。