对象数组中属性值的递归数组

时间:2019-08-03 20:53:44

标签: javascript arrays recursion

我需要的是一组属性值,从一组对象中递归收集,这就是我的意思:

const regions = [{
  name: 'Europe',
  subRegions: [{
    name: 'BeNeLux',
    territories: [{
      code: 'NL',
      name: 'Netherlands'
    }, {
      code: 'DE',
      name: 'Germany'
    }, {
      code: 'LU',
      name: 'Luxembourgh'
    }]
  }],
  territories: [{
    code: 'UK',
    name: 'United Kingdom'
  }, {
    code: 'AL',
    name: 'Albania'
  }, {
    code: 'ZW',
    name: 'Switzerland'
  }]
}]

我想在regions数组中获取所有国家/地区代码的数组。

类似:

const expectedOutput = ['NL', 'DE', 'LU', 'AL', 'ZW', 'UK'];

这是我尝试过的方法,部分可以奏效,但不能正确地收集它(我也很想探索其他/功能性设置来解决此问题)

const getAllTerritoryCodesFromRegions = regions => {
  return regions
    .reduce(function r (output, region) {
      if (region?.subRegions?.length) {
        output.subRegions = region.subRegions.reduce(r, output)
      }

      if (region?.territories?.length) {
        output = [
          ...output,
          ...region.territories.map(t => t.code)
        ]
      }

      return output
    }, [])
}

3 个答案:

答案 0 :(得分:2)

假设code属性应始终包含国家/地区代码:

在第一个调用中创建一个一个数组可能比为每个调用创建一个数组并在以后尝试将其组合起来要容易。然后,您只需要forEach遍历区域和领土,然后将代码推送到该数组:

const regions = [{
  name: 'Europe',
  subRegions: [{
    name: 'BeNeLux',
    territories: [{
      code: 'NL',
      name: 'Netherlands'
    }, {
      code: 'DE',
      name: 'Germany'
    }, {
      code: 'LU',
      name: 'Luxembourgh'
    }]
  }],
  territories: [{
    name: 'United Kingdom',
    code: 'UK'
  }, {
    code: 'AL',
    name: 'Albania'
  }, {
    code: 'ZW',
    name: 'Switzerland'
  }]
}];

const getAllTerritoryCodesFromRegions = (regions, allCodes=[]) => {
  regions.forEach(({ territories, subRegions }) => {
    if (territories) {
      territories.forEach(({ code }) => {
        allCodes.push(code);
      });
    }
    if (subRegions) {
      getAllTerritoryCodesFromRegions(subRegions, allCodes);
    }
  });
  return allCodes;
};
console.log(
  getAllTerritoryCodesFromRegions(regions)
);

答案 1 :(得分:2)

您可以通过查找数组来缩小数组并返回代码。

function getCodes(array) {
    return array.reduce((r, o) => {
        if ('code' in o) {
            r.push(o.code);
            return r;
        }
        Object.values(o).forEach(v => {
            if (Array.isArray(v)) r.push(...getCodes(v));
        });
        return r;
    }, []);
}

const
    regions = [{ name: 'Europe', subRegions: [{ name: 'BeNeLux', territories: [{ code: 'NL', name: 'Netherlands' }, { code: 'DE', name: 'Germany' }, { code: 'LU', name: 'Luxembourgh' }] }], territories: [{ name: 'United Kingdom', code: 'UK' }, { name: 'AL', code: 'Albania' }, { name: 'ZW', code: 'Switzerland' }] }],
    codes = getCodes(regions);

console.log(codes);

答案 2 :(得分:1)

您可以使用递归方法

const getAllTerritoryCodesFromRegions = array => {
    const output = [];

    array.forEach(item => {
        for (const key in item) {
            if (key === 'code') {
                output.push(item[key]);
            } else if (item.hasOwnProperty(key) && Array.isArray(item[key])) {
                const childOutput = getAllTerritoryCodesFromRegions(item[key]);
                output.push(...childOutput);
            }
        }
    });

    return output;
}

您可以在jsfiddle上找到有效的示例。但是,在示例数据集中,您弄乱了一些名称和代码。