3

我在按条件合并 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

4

2 回答 2

2

rockType is overwritten each repeat of the loop:

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

You should store the result in another variable this way:

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

Here is the result: https://codesandbox.io/s/tender-ritchie-i0qkt

于 2019-05-31T07:31:18.007 回答
1

我不知道您的确切要求,但我发现了导致问题的原因问题出在减速器的 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
          };
        }

Every time loop runs and it found match your it replaces your rockType content as it is an object not an array.

other solution takes an empty array outside forEach and push the contents in the inside if condition and spread it while returning.

Just saying you should consider refactoring your code.

于 2019-05-31T07:31:16.053 回答