【问题标题】:filter data from an array of objects based on another array of objects根据另一个对象数组从对象数组中过滤数据
【发布时间】:2020-08-15 21:27:18
【问题描述】:

我有任何对象数组:

array1 = [
    {id: "1", policy: "abc", date: "20-05-2019" },
    {id: "4", policy: "hjk", date: "12-05-2019" },
    {id: "5", policy: "ikl", date: "08-05-2019" },
    {id: "7", policy: "qwe", date: "20-05-2019" },
    {id: "8", policy: "bdd", date: "04-05-2019" },
]

我有另一个像这样的大数组:

array2 = [
 {
   "info" : { "insuredPolicy" : "qwe", },
   "date" : { "sDate" : 20-05-2019, "eDate" : 20-06-2019 }
 },
 {
   "info" : { "insuredPolicy" : "ikl", },
   "date" : { "sDate" : 20-05-2019, "eDate" : 20-06-2019 }
 },
{
   "info" : { "insuredPolicy" : "bbb", },
   "date" : { "sDate" : 20-05-2019, "eDate" : 20-06-2019 }
 },
{
   "info" : { "insuredPolicy" : "bdd", },
   "date" : { "sDate" : 04-05-2019, "eDate" : 20-05-2019 }
 },
];

我想将 array1 中的所有策略字段和日期字段与 array2 进行比较(假设 array2 非常大)。 然后,如果策略字段(数组 1)与保险策略(数组 2)匹配,并且数组 1 中的日期字段与数组 2 中的 sDate 匹配,则创建对象数组

所以输出将是:

array3 = [
{ policy: "qwe", date: "20-05-2019" },
{ policy: "bdd", date: "04-05-2019" },
];

在学习阶段,任何帮助将不胜感激。

编辑

如何比较 array2 是否提前一天包含 sDate?如果是这样,则将 sDate 减少 1 天,然后进行比较。我们怎样才能做到这一点?

提前致谢。

【问题讨论】:

    标签: javascript arrays node.js object filter


    【解决方案1】:

    您可以将对象作为映射,并为第一个数组递增,第二个数组递减。最后只取值为零的键并将键解析为 JSON 以获取新对象。

    var array1 = [{ id: "1", policy: "abc", date: "20-05-2019" }, { id: "4", policy: "hjk", date: "12-05-2019" }, { id: "5", policy: "ikl", date: "08-05-2019" }, { id: "7", policy: "qwe", date: "20-05-2019" }, { id: "8", policy: "bdd", date: "04-05-2019" }],
        array2 = [{ info: { insuredPolicy: "qwe" }, date: { sDate: "20-05-2019", eDate: "20-06-2019" } }, { info: { insuredPolicy: "ikl" }, date: { sDate: "20-05-2019", eDate: "20-06-2019" } }, { info: { insuredPolicy: "bbb" }, date: { sDate: "20-05-2019", eDate: "20-06-2019" } }, { info: { insuredPolicy: "bdd" }, date: { sDate: "04-05-2019", eDate: "20-05-2019" } }],
        wrapper1 = ({ policy, date }) => JSON.stringify({ policy, date }),
        wrapper2 = ({ info: { insuredPolicy: policy }, date: { sDate: date } }) => JSON.stringify({ policy, date }),
        map = Object.create(null),
        setMap = (map, wrapper, value) => object => (key => map[key] = (map[key] || 0) + value)(wrapper(object)),
        result;
    
    array1.forEach(setMap(map, wrapper1, 1));
    array2.forEach(setMap(map, wrapper2, -1));
    
    result = Object
        .entries(map)
        .filter(([, v]) => !v)
        .map(([k]) => JSON.parse(k));
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      【解决方案2】:

      您可以在array1 上使用Array#filter 和在array2 上使用Array#some 来过滤掉所需的元素。

      const array1 = [{id: "1", policy: "abc", date: "20-05-2019" },{id: "4", policy: "hjk", date: "12-05-2019" },{id: "5", policy: "ikl", date: "08-05-2019" },{id: "7", policy: "qwe", date: "20-05-2019" },{id: "8", policy: "bdd", date: "04-05-2019" },]
      
      const array2 = [{"info" : { "insuredPolicy" : "qwe", },"date" : { "sDate" : '20-05-2019', "eDate" : '20-06-2019' }},
      {"info" : { "insuredPolicy" : "ikl", },"date" : { "sDate" : '20-05-2019', "eDate" : '20-06-2019' }},{"info" : { "insuredPolicy" : "bbb", },"date" : { "sDate" : '20-05-2019', "eDate" : '20-06-2019' }},{"info" : { "insuredPolicy" : "bdd", },"date" : { "sDate" : '04-05-2019', "eDate" : '20-05-2019' }},];
      
      
       let out = array1.filter(({policy, date}) => array2.some(e => e.info.insuredPolicy === policy && e.date.sDate === date));
       console.log(out)

      编辑:根据新要求

      您可以编写一个方法来获取上一个日期字符串,如下所示

      const array1 = [{id: "1", policy: "abc", date: "20-05-2019" },{id: "4", policy: "hjk", date: "12-05-2019" },{id: "5", policy: "ikl", date: "08-05-2019" },{id: "7", policy: "qwe", date: "20-05-2019" },{id: "8", policy: "bdd", date: "04-05-2019" },]
      
      const array2 = [{"info" : { "insuredPolicy" : "qwe", },"date" : { "sDate" : '21-05-2019', "eDate" : '20-06-2019' }},
      {"info" : { "insuredPolicy" : "ikl", },"date" : { "sDate" : '20-05-2019', "eDate" : '20-06-2019' }},{"info" : { "insuredPolicy" : "bbb", },"date" : { "sDate" : '20-05-2019', "eDate" : '20-06-2019' }},{"info" : { "insuredPolicy" : "bdd", },"date" : { "sDate" : '04-05-2019', "eDate" : '20-05-2019' }},];
      
      
      function yesterday(str) {
        return str.replace(/\d{2}/, (p1) => (p1 - 1).toString().padStart(2, 0))
      }
      
      let out = array1.filter(({policy, date}) => array2.some(e => e.info.insuredPolicy === policy && yesterday(e.date.sDate) === date));
       console.log(out)

      【讨论】:

      • 有问题需要进行小编辑,需要减少一天的 sDate 然后与日期进行比较。 eg: 如果 sDate 是 05-05-2019,则减少一天并与 array1 中的日期进行比较。
      • @Vishnu 也为此添加了解决方案。
      【解决方案3】:

      您可以使用过滤器和地图

      1. 由于您提到第二个数组非常大,因此每次搜索完整数组都会增加时间复杂度
      2. 所以使用 Map 将第二个数组映射到一个键值对
      3. 根据 Mapper 中存在的值过滤 array1 中的值

      const array1 = [{id: "1", policy: "abc", date: "20-05-2019" },{id: "4", policy: "hjk", date: "12-05-2019" },{id: "5", policy: "ikl", date: "08-05-2019" },{id: "7", policy: "qwe", date: "20-05-2019" },{id: "8", policy: "bdd", date: "04-05-2019" },]
      
      const array2 = [{"info" : { "insuredPolicy" : "qwe", },"date" : { "sDate" : '20-05-2019', "eDate" : '20-06-2019' }},
      {"info" : { "insuredPolicy" : "ikl", },"date" : { "sDate" : '20-05-2019', "eDate" : '20-06-2019' }},{"info" : { "insuredPolicy" : "bbb", },"date" : { "sDate" : '20-05-2019', "eDate" : '20-06-2019' }},{"info" : { "insuredPolicy" : "bdd", },"date" : { "sDate" : '04-05-2019', "eDate" : '20-05-2019' }},];
      
      const mapper = new Map(array2.map(({
        info,
        date
      }) => [info.insuredPolicy, date.sDate]))
      
      const final = array1.filter(({
        policy,
        date
      }) => {
        if (mapper.has(policy)) {
          return mapper.get(policy) === date
        }
      })
      
      console.log(final)

      【讨论】:

      • 有问题需要进行小编辑,需要减少一天的 sDate 然后与日期进行比较。 eg: 如果 sDate 是 05-05-2019,则减少一天并与 array1 中的日期进行比较。
      • @Vishnu 使用 new Date 解析日期并以所需的方式进行操作,或者如果您的项目有很多与日期相关的操作,请使用标准库,如 moment 或 date-fns
      • 你能用moment或date-fns更新吗?这将非常有帮助。
      • @Vishnu 出于尊重,您必须首先尝试至少一次,如果您仍然面临您可以在这里提问,您将自己学习,尝试一次,如果您仍然知道,请告诉我面对困难,快乐编码
      • 是的,可以,请告诉我这里使用了 Map 的乳清吗?我没明白重点。
      【解决方案4】:

      您可以使用.reduce() 根据您的条件创建新数组

      var array1 = [
          {id: "1", policy: "abc", date: "20-05-2019" },
          {id: "4", policy: "hjk", date: "12-05-2019" },
          {id: "5", policy: "ikl", date: "08-05-2019" },
          {id: "7", policy: "qwe", date: "20-05-2019" },
          {id: "8", policy: "bdd", date: "04-05-2019" },
      ]
      
      var array2 = [
       {
         "info" : { "insuredPolicy" : "qwe", },
         "date" : { "sDate" : "20-05-2019", "eDate" : "20-06-2019" }
       },
       {
         "info" : { "insuredPolicy" : "ikl", },
         "date" : { "sDate" : "20-05-2019", "eDate" : "20-06-2019" }
       },
      {
         "info" : { "insuredPolicy" : "bbb", },
         "date" : { "sDate" : "20-05-2019", "eDate" : "20-06-2019" }
       },
      {
         "info" : { "insuredPolicy" : "bdd", },
         "date" : { "sDate" : "04-05-2019", "eDate" : "20-05-2019" }
       },
      ];
      
      console.log(array2.reduce((arr, { info: { insuredPolicy }, date: { sDate } }) => {
        var item = array1.find(({ policy, date }) => insuredPolicy == policy && sDate == date)
        if(item) arr.push({ policy: item.policy, date: item.date }) // edit as you want
        return arr
      }, []))

      【讨论】:

      • 有问题需要进行小编辑,需要减少一天的 sDate 然后与日期进行比较。 eg: 如果 sDate 是 05-05-2019,则减少一天并与 array1 中的日期进行比较。
      猜你喜欢
      • 2021-10-24
      • 2022-11-30
      • 2019-09-30
      • 2019-04-05
      • 2022-11-01
      • 2019-09-15
      • 1970-01-01
      • 1970-01-01
      • 2023-01-13
      相关资源
      最近更新 更多