使用递归方法展开一个包含对象和数组的深度嵌套数组

3

我有一个包含另一个对象数组的对象数组,嵌套层级为四级。 该数组结构如下:

[
  {
    title: 'Title',
    type: 'section',
    links: [
      {
        label: 'Label',
        id: 'id_1',
        links: [
          {
            title: 'Title',
            type: 'section',
            links: [
              {
                label: 'Label',
                id: 'id_2',
                links: [
                  {
                    label: 'Label',
                    id: 'id_3',
                    links: [],
                  }
                ]
              }
            ]
          },
          {
            title: 'Other title',
            type: 'section',
            links: [
              {
                label: 'Label',
                id: 'id_4',
                links: [],
              }
            ]
          }
        ]
      }
    ]
  }
]

我希望能够获得一个扁平化的数组,其中包含包含链接的链接数组的ID(它们是子菜单的父级)。因此,期望的结果如下所示:["id_1", "id_2"]

我尝试使用从MDN获取的以下函数来获得结果:

flatDeep(arr, d = 1) {
  return d > 0
    ? arr.reduce((acc, val) =>
      acc.concat(Array.isArray(val.links)
        ? this.flatDeep(val.links, d - 1)
        : val.links), [])
    : arr.slice();
}

这让我得到了一个空数组。

所以,你只是想从给定的对象数组中得到一个类似于["id_1", "id_2"]的数组吗? - palaѕн
5个回答

2
使用Array.flatMap()。解构每个对象,并使用空数组作为缺失的id值的默认值。将id和递归展平链接的结果连接起来。

const flattenIds = arr => arr.flatMap(({ id = [], links }) => 
  [].concat(id, flattenIds(links))
);
    
const data = [{ title: 'Title', type: 'section', links: [{ label: 'Label', id: 'id_1', links: [{ title: 'Title', type: 'section', links: [{ label: 'Label', id: 'id_2', links: [{ label: 'Label', id: 'id_3', links: [] }] }] }, { title: 'Other title', type: 'section', links: [{ label: 'Label', id: 'id_4', links: [] }] }] }] }];

const result = flattenIds(data);

console.log(result);


1
您可以通过递归和检查缺失属性的id来获得一个扁平化的数组。

const
    getId = ({ id, links }) => [
        ...(id === undefined ? [] : [id]),
        ...links.flatMap(getId)
    ],
    data = [{ title: 'Title', type: 'section', links: [{ label: 'Label', id: 'id_1', links: [{ title: 'Title', type: 'section', links: [{ label: 'Label', id: 'id_2', links: [{ label: 'Label', id: 'id_3', links: [] }] }] }, { title: 'Other title', type: 'section', links: [{ label: 'Label', id: 'id_4', links: [] }] }] }] }],
    result = data.flatMap(getId);

console.log(result);


谢谢 Nina!我添加了一个检查空链接数组的代码,其中检查了未定义的 id,以返回仅具有链接的 id。 - Gert-Jan Kooijmans

1
这是一个非递归版本。

const data = [{title:'Title',type:'section',links:[{label:'Label',id:'id_1',links:[{title:'Title',type:'section',links:[{label:'Label',id:'id_2',links:[{label:'Label',id:'id_3',links:[]}]}]},{title:'Other title',type:'section',links:[{label:'Label',id:'id_4',links:[]}]}]}]}];

const stack = data.slice();
const result = [];

let obj;
while (obj = stack.shift()) {
  if ("id" in obj && obj.links.length > 0) result.push(obj.id);
  stack.push(...obj.links);
}

console.log(result);

这里使用了广度优先搜索,但可以轻松地改为深度优先搜索。您只需将stack.push调用更改为stack.unshift即可。
有关这两者的更详细解释,请查看广度优先搜索与深度优先搜索

0

var array = JSON.parse('[{"title":"Title","type":"section","links":[{"label":"Label","id":"id_1","links":[{"title":"Title","type":"section","links":[{"label":"Label","id":"id_2","links":[{"label":"Label","id":"id_3","links":[]}]}]},{"title":"Other title","type":"section","links":[{"label":"Label","id":"id_4","links":[]}]}]}]}]');


arr = [];
 while(array.length != 0) {
  var ob1 = array.splice(0,1)[0];
  for(var ob2 of ob1.links) {
    if (ob2.links.length !== 0) {
      arr.push(ob2.id);
      array = array.concat(ob2.links);
    }
  }
 }

console.log(arr);

这是您请求的输出结果:

[
  "id_1",
  "id_2"
]

0

我认为递归函数会简化问题。(递归查找lists数组并将id推入res)。

const data = [
  {
    title: "Title",
    type: "section",
    links: [
      {
        label: "Label",
        id: "id_1",
        links: [
          {
            title: "Title",
            type: "section",
            links: [
              {
                label: "Label",
                id: "id_2",
                links: [
                  {
                    label: "Label",
                    id: "id_3",
                    links: []
                  }
                ]
              }
            ]
          },
          {
            title: "Other title",
            type: "section",
            links: [
              {
                label: "Label",
                id: "id_4",
                links: []
              }
            ]
          }
        ]
      }
    ]
  }
];

const res = [];

const ids = data => {
  data.forEach(item => {
    if ("id" in item) {
      res.push(item.id);
    }
    if (item.links) {
      ids(item.links);
    }
  });
};

ids(data);
console.log(res);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接