首页 > 解决方案 > 如何更好地使用 .flatMap()、.map() 和 .filter() 在 Javascript 中迭代和过滤嵌套数组

问题描述

我有以下数据,我需要过滤它们并以特定格式获取一些信息:

const parentInfo = [
{
    childInfo: [
        {
            type: 'new',
            testOne: { subTestOne: '111' },
            testTwo: 'bbb',
            testThree: { subTestThree: '666' },
            testFour: 'ddd',
            testFive: 'eee',
        },
        {
            type: 'old',
            testOne: { subTestOne: '222' },
            testTwo: 'ggg',
            testThree: { subTestThree: '777' },
            testFour: 'iii',
            testFive: 'jjj',
        },
        {
            type: 'new',
            testOne: { subTestOne: '333' },
            testTwo: 'lll',
            testThree: { subTestThree: '888' },
            testFour: 'nnn',
            testFive: 'ooo',
        }
    ]
},
{
    childInfo: [
        {
            type: 'new',
            testOne: { subTestOne: '444' },
            testTwo: 'qqq',
            testThree: { subTestThree: '999' },
            testFour: 'sss',
            testFive: 'ttt',
        },
        {
            type: 'old',
            testOne: { subTestOne: '555' },
            testTwo: 'vvv',
            testThree: { subTestThree: '000' },
            testFour: 'xxx',
            testFive: 'yyy',
        }
    ]
},
]

我需要输出为:

{
   allOnes: ['111', '333', '444'],
   allTwos: ['bbb', 'lll', 'qqq'],
   allThrees: ['666', '888', '999'],
   allFours: ['ddd', 'nnn', 'sss'],
   allFives: ['eee', 'ooo', 'ttt']
}

我设法用下面的代码得到了我需要的东西,但我认为我使用的迭代次数比需要的多。我找不到使它更简单或至少更紧凑的方法。有什么建议么?

 const getInfo = (parentInfo) => {

  const allOnes = parentInfo.flatMap(({
      childInfo
    }) =>
    childInfo
    .filter((childSingleInfo) => childSingleInfo.type === 'new')
    .map((childSingleInfo) => childSingleInfo.testOne.subTestOne),
  );

  const allTwos = parentInfo.flatMap(({
      childInfo
    }) =>
    childInfo
    .filter((childSingleInfo) => childSingleInfo.type === 'new')
    .map((childSingleInfo) => childSingleInfo.testTwo),
  );

  const allThrees = parentInfo.flatMap(({
      childInfo
    }) =>
    childInfo
    .filter((childSingleInfo) => childSingleInfo.type === 'new')
    .map((childSingleInfo) => childSingleInfo.testThree.subTestThree),
  );

  const allFours = parentInfo.flatMap(({
      childInfo
    }) =>
    childInfo
    .filter((childSingleInfo) => childSingleInfo.type === 'new')
    .map((childSingleInfo) => childSingleInfo.testFour),
  );

  const allFives = parentInfo.flatMap(({
      childInfo
    }) =>
    childInfo
    .filter((childSingleInfo) => childSingleInfo.type === 'new')
    .map((childSingleInfo) => childSingleInfo.testFive),
  );

  return {
      allOnes: allOnes.length
          ? Array.from(new Set(allOnes)).join(', ')
          : null,
      allTwos: allTwos.length
          ? Array.from(new Set(allTwos)).join(', ')
          : null,
      allThrees: allThrees.length
          ? Array.from(new Set(allThrees)).join(', ')
          : null,
      allFours: allFours.length
          ? Array.from(new Set(allFours)).join(', ')
          : null,
      allFives: allFives.length
          ? Array.from(new Set(allFives)).join(', ')
          : null,
    };
}

这是我的代码的小提琴:https ://jsfiddle.net/rf6kL2s3/

我已经更新了代码以更好地反映实际数据。

标签: javascript

解决方案


您可以创建一个地图对象,以保持 childInfo 道具和生成的道具之间的关系,例如 allOnes:“testOne”。使用Array.prototype.reduce()

const parentInfo =  [{ childInfo: [{ type: 'new', testOne: 'aaa', testTwo: 'bbb', testThree: 'ccc', testFour: 'ddd', testFive: 'eee' }, { type: 'old', testOne: 'fff', testTwo: 'ggg', testThree: 'hhh', testFour: 'iii', testFive: 'jjj' }, { type: 'new', testOne: 'kkk', testTwo: 'lll', testThree: 'mmm', testFour: 'nnn', testFive: 'ooo' }] }, { childInfo: [{ type: 'new', testOne: 'ppp', testTwo: 'qqq', testThree: 'rrr', testFour: 'sss', testFive: 'ttt' }, { type: 'old', testOne: 'uuu', testTwo: 'vvv', testThree: 'www', testFour: 'xxx', testFive: 'yyy' }] }];

const maps = {allOnes: "testOne", allTwos: "testTwo",allThrees: "testThree",allFours: "testFour", allFives: "testFive"};

const result = parentInfo.reduce((res, current) => {
   const newElements = current.childInfo.filter(item => item.type === "new");
   Object.entries(maps).map(([key, value]) => {
     res[key] = [...res[key] || [], ...newElements.map(item => item[value])]
   })
  return res;
 }, {});


console.log(result)


推荐阅读