使用扩展运算符减少ES6中缺失的嵌套对象数组

3

我有一个问题,在根据条件合并两组数据时遇到了困难。我调试了一小时以上,仍然无法找出原因。下面是一个我创建的示例。

我有这两组数据:

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"},我想知道我的错误在哪里。Omit是lodash的omit函数,但我不认为这是罪魁祸首。我在这里创建了一个演示:https://codesandbox.io/s/condescending-platform-1jp9l?fontsize=14&previewwindow=tests

什么是 omit?如果它来自于依赖项,请包含导入。 - Jake Worth
你能否也发布省略方法?我无法完全理解。 - Janith
@JakeWorth lodash的omit函数。 - Hanz
@Janith 我认为那不是问题。 - Hanz
2个回答

2

每次循环都会覆盖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

1

我不知道你的具体要求,但我找到了导致问题的原因。问题出在你的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外部使用一个空数组,并在内部条件中推入内容,同时在返回时展开它。
只是说您应该考虑重构您的代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接