繁体   English   中英

使用spread减少es6缺少嵌套的对象数组

[英]reduce es6 missing nested array of object using spread

我遇到了根据条件合并2组数据的问题。 我调试了一个多小时,但无法弄清楚原因。 我在下面创建了一个示例。

我有这两个数据:

const staticRockData = {
    rockTypes: [
      {
        supplierRockTypes: [
          {
            rockCodes: ["1"],
            match_id: "abc"
          },
          {
            rockCodes: ["2"],
            match_id: "abc"
          }
        ]
      }
    ]
  };

  const gatewayRockData = {
    match_id: "abc",
    rocks: [{ rock_type: "1", rates: [] }, { rock_type: "2", rates: [] }]
  };

我有这个映射逻辑:

let rockTypes = staticRockData.rockTypes;

  rockTypes = rockTypes.reduce((accum, rockType) => {
    const matchedSourceId = rockType.supplierRockTypes.some(
      o2 => o2.match_id === gatewayRockData.match_id
    );
    if (matchedSourceId) {
      gatewayRockData.rocks.forEach(rock => {
        const matchRockType = rockType.supplierRockTypes.some(o2 => {
          return o2.rockCodes.includes(rock.rock_type);
        });

        if (matchRockType) {
          console.log("rock.rock_type", rock.rock_type);
          rockType = {
            ...rockType,
            rock_type: rock.rock_type,
            rates: rock.rates
          };
        }
      });
    }

    accum = [...accum, { ...omit(rockType, "supplierRockTypes") }];

    return accum;
  }, []);

  return {
    rocks: rockTypes
  };

我期待这个:

rocks: [
       {
         rates: [],
         rock_type: "1"
       },
       {
         rates: [],
         rock_type: "2"
       }
     ]
   }

目前的解决方案缺少这个:

{ rates: [], rock_type: "1"} ,我想知道我的错误在哪里。

忽略是lodash的omit功能,但我认为这不是罪魁祸首。 我在这里创建了一个演示:

https://codesandbox.io/s/condescending-platform-1jp9l?fontsize=14&previewwindow=tests

每次重复循环时都会覆盖rockType:

rockType = {
        ...rockType,
        rock_type: rock.rock_type,
        rates: rock.rates
      };

您应该以这种方式将结果存储在另一个变量中:

...
let matchedRockTypes = [];
if (matchedSourceId) {
  gatewayRockData.rocks.forEach(rock => {
    const matchRockType = rockType.supplierRockTypes.some(o2 => {
      return o2.rockCodes.includes(rock.rock_type);
    });

    if (matchRockType) {
      console.log("rock.rock_type", rock.rock_type);
      matchedRockTypes.push({
        rock_type: rock.rock_type,
        rates: rock.rates
      });
    }
  });
}
return matchedRockTypes;
...

结果如下: https//codesandbox.io/s/tender-ritchie-i0qkt

我不知道你的具体要求,但我发现导致问题的原因问题出在你的reducer的forEach中,这个问题在下面的版本中得到修复:

rockTypes = rockTypes.reduce((accum, rockType) => {
    const matchedSourceId = rockType.supplierRockTypes.some(
      o2 => o2.match_id === gatewayRockData.match_id
    );
    if (matchedSourceId) {
      gatewayRockData.rocks.forEach(rock => {
        const matchRockType = rockType.supplierRockTypes.some(o2 => {
          return o2.rockCodes.includes(rock.rock_type);
        });

        if (matchRockType) {
          accum = [...accum, { rock_type: rock.rock_type,
            rates: rock.rates }];;
        }
      });
    }

    return accum;
  }, []);

更具体地说,在forEach下面的行:

if (matchRockType) {
          rockType = {
            ...rockType,
            rock_type: rock.rock_type,
            rates: rock.rates
          };
        }

每次循环运行并且找到匹配的时候它会替换你的rockType内容,因为它是一个对象而不是一个数组。

其他解决方案在forEach外部获取一个空数组,并在内部推送内容if条件并在返回时传播它。

只是说你应该考虑重构你的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM