首页 > 解决方案 > 为递归/嵌套对象数组中的所有路径创建一个键映射

问题描述

我有一个带有标题和 ID 的深度嵌套的标签对象数组。我要创建的是一个对象,其 ID 作为键,值是描述该 ID 的标题路径的数组。

我不是递归大师,所以我下面的尝试并不能完全提供我需要的结果。

这是原始的嵌套标签数组:

const tags = [
  {
    title: 'Wood',
    id: 'dkgkeixn',
    tags: [
      {
        title: 'Material',
        id: 'ewyherer'
      },
      {
        title: 'Construction',
        id: 'cchtfyjf'
      }
    ]
  },
  {
    title: 'Steel',
    id: 'drftgycs',
    tags: [
      {
        title: 'Surface',
        id: 'sfkstewc',
        tags: [
          {
            title: 'Polished',
            id: 'vbraurff'
          },
          {
            title: 'Coated',
            id: 'sdusfgsf'
          }
        ]
      },
      {
        title: 'Quality',
        id: 'zsasyewe'
      }
    ]
  }
]

我想要得到的输出是这样的:

{
  'dkgkeixn': ['Wood'],
  'ewyherer': ['Wood', 'Material'],
  'cchtfyjf': ['Wood', 'Construction'],
  'drftgycs': ['Steel'],
  'sfkstewc': ['Steel', 'Surface'],
  'vbraurff': ['Steel', 'Surface', 'Polished'],
  'sdusfgsf': ['Steel', 'Surface', 'Coated'],
  'zsasyewe': ['Steel', 'Quality']
}

所以我正在构建这个递归函数,它几乎可以完成它的工作,但我的平面/键映射中不断出现错误的路径:

function flatMap(tag, acc, pathBefore) {
  if (!acc[tag.id]) acc[tag.id] = [...pathBefore];
  acc[tag.id].push(tag.title);

  if (tag.tags) {
    pathBefore.push(tag.title)
    tag.tags.forEach(el => flatMap(el, acc, pathBefore))
  }
  return acc
}

const keyMap = flatMap({ title: 'Root', id: 'root', tags}, {}, []);
console.log("keyMap", keyMap)

我试图获取路径,直到没有标签的标签,然后将该路径设置为 ID 的值,然后推送项目“自己的”标题。但不知何故,路径变得一团糟。

标签: javascriptarraysjsonrecursionnested

解决方案


检查这个,makePaths参数是tagsresult object 和prefixed 标题。

const makePaths = (tags, res = {}, prefix = []) => {
  tags.forEach(tag => {
    const values = [...prefix, tag.title];
    Object.assign(res, { [tag.id]: values });
    if (tag.tags) {
      makePaths(tag.tags, res, values);
    }
  });
  return res;
};

const tags = [
  {
    title: "Wood",
    id: "dkgkeixn",
    tags: [
      {
        title: "Material",
        id: "ewyherer"
      },
      {
        title: "Construction",
        id: "cchtfyjf"
      }
    ]
  },
  {
    title: "Steel",
    id: "drftgycs",
    tags: [
      {
        title: "Surface",
        id: "sfkstewc",
        tags: [
          {
            title: "Polished",
            id: "vbraurff"
          },
          {
            title: "Coated",
            id: "sdusfgsf"
          }
        ]
      },
      {
        title: "Quality",
        id: "zsasyewe"
      }
    ]
  }
];

console.log(makePaths(tags));


推荐阅读