уменьшить es6 отсутствующий вложенный массив объекта, используя распространение - PullRequest
3 голосов
/ 31 мая 2019

У меня проблема с объединением двух наборов данных по условию. Я отлаживал больше часа, но не мог понять почему. Я создал образец ниже.

У меня есть 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"}, интересно, где моя ошибка.

Пропустить - это функция Лодаша omit, но я не думаю, что это виновник. Я создал демо здесь:

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

Ответы [ 2 ]

2 голосов
/ 31 мая 2019

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 голос
/ 31 мая 2019

Я не знаю ваших точных требований, но я выяснил, что является причиной проблемы Проблема в 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 и распространяет его при возврате.

Просто говорю, что вам следует подумать о рефакторинге вашего кода.

...