扁平化一个数组树js

时间:2020-12-18 18:24:58

标签: javascript arrays flat

你能帮我把这棵树弄平吗? 我已经尝试了几件事,但没有奏效。 我想得到最快的方法(算法)。

const source = [
  {
    item: { id: 1, name: "item name", code: "1d4g4" },
    children: [
      {
        item: { id: 2, name: "item name 2", code: "1d4g4" },
        children: [
          {
            item: { id: 2, name: "item name 2", code: "1d4g4" },
            children: [
              {
                item: { id: 3, name: "item name 2", code: "1d4g4" },
                children: [
                  { item: { id: 4, name: "item name 2", code: "1d4g4" }, children: [] },
                  { item: { id: 4, name: "item name 2", code: "1d4g4" }, children: [] },
                  { item: { id: 4, name: "item name 2", code: "1d4g4" }, children: [] },
                ],
              },
            ],
          },
        ],
      },
    ],
  },
];

这是我希望得到的结果:

  { id: 1, name: 'item name', code: '1d4g4' },
  { id: 2, name: 'item name 2', code: '1d4g4' },
  { id: 2, name: 'item name 2', code: '1d4g4' },
  { id: 3, name: 'item name 2', code: '1d4g4' },
  { id: 4, name: 'item name 2', code: '1d4g4' },
  { id: 4, name: 'item name 2', code: '1d4g4' },
  { id: 4, name: 'item name 2', code: '1d4g4' }
]```

4 个答案:

答案 0 :(得分:2)

您可以使用 Array#flatMap 和一个调用自身的回调函数。

const
    flat = ({ item, children = [] }) => [item, ...children.flatMap(flat)],
    data = [{ item: { id: 1, name: "item name", code: "1d4g4" }, children: [{ item: { id: 2, name: "item name 2", code: "1d4g4" }, children: [{ item: { id: 2, name: "item name 2", code: "1d4g4" }, children: [{ item: { id: 3, name: "item name 2", code: "1d4g4" }, children: [{ item: { id: 4, name: "item name 2", code: "1d4g4" }, children: [] }, { item: { id: 4, name: "item name 2", code: "1d4g4" }, children: [] }, { item: { id: 4, name: "item name 2", code: "1d4g4" }, children: [] }] }] }] }] }],
    result = data.flatMap(flat);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:1)

在将您的语法修正为实际有效的 JavaScript 之后,您将需要一个递归函数:

function flatten(destArray, nodeList) {
  nodeList.forEach((node) => {
    destArray.push(node.item);
    flatten(destArray, node.children || []);
  });
}

const source = [
  {
    item: { id: 1, name: "item name", code: "1d4g4" },
    children: [
      {
        item: { id: 2, name: "item name 2", code: "1d4g4" },
        children: [
          {
            item: { id: 2, name: "item name 2", code: "1d4g4" },
            children: [
              {
                item: { id: 3, name: "item name 2", code: "1d4g4" },
                children: [
                  { item: { id: 4, name: "item name 2", code: "1d4g4" }, children: [] },
                  { item: { id: 4, name: "item name 2", code: "1d4g4" }, children: [] },
                  { item: { id: 4, name: "item name 2", code: "1d4g4" }, children: [] },
                ],
              },
            ],
          },
        ],
      },
    ],
  },
];

const dest = [];
flatten(dest, source);
console.log(dest);

输出

[
  { id: 1, name: 'item name', code: '1d4g4' },
  { id: 2, name: 'item name 2', code: '1d4g4' },
  { id: 2, name: 'item name 2', code: '1d4g4' },
  { id: 3, name: 'item name 2', code: '1d4g4' },
  { id: 4, name: 'item name 2', code: '1d4g4' },
  { id: 4, name: 'item name 2', code: '1d4g4' },
  { id: 4, name: 'item name 2', code: '1d4g4' }
]

答案 2 :(得分:0)

您可以编写一个内部 visit 方法来处理遍历树并将项目添加到内部 results 列表中。

注意:确保您的 JS/JSON 数据结构正确。

const tree = [{
  item: {id: 1, name: "item name", code: "1d4g4"},
  children: [{
    item: {id: 2, name: "item name 2", code: "1d4g4"},
    children: [{
      item: {id: 2, name: "item name 2", code: "1d4g4"},
      children: [{
        item: {id: 3, name: "item name 2", code: "1d4g4"},
        children:[
          {item: {id: 4, name: "item name 2", code: "1d4g4"}, children: []},
          {item: {id: 4, name: "item name 2", code: "1d4g4"}, children: []},
          {item: {id: 4, name: "item name 2", code: "1d4g4"}, children: []},
        ]
      }]
    }]
  }]
}];

const treeToList = (tree, results = []) => {
  const visit = ({ item, children = [] }, res) => {
    if (item) res.push(item);
    children.forEach(child => visit(child, res));
  }
  visit({ children: tree }, results);
  return results;
}

console.log(treeToList(tree));
.as-console-wrapper { top: 0; max-height: 100% !important; }

答案 3 :(得分:0)

<块引用>
const flatten = (data) => data.map(({ children }) => ([...flatten(children)]));

您当前的代码确实遍历了整棵树,但从未真正从数据中提取 item。另一个问题是您当前使用 map,这意味着结果值将始终具有与初始数组相同数量的元素。使用 flatMap 增加或减少数组中的元素数量。

尽可能少地更改您的代码,它可能如下所示:

const flatten = (data) => data.flatMap(({item, children}) => ([item, ...flatten(children)]));

const flatten = (data) => data.flatMap(({item, children}) => ([item, ...flatten(children)]));

const data = [{
  item: {id: 1, name: "item name", code: "1d4g4"},
  children: [{
    item: {id: 2, name: "item name 2", code: "1d4g4"},
    children: [{
      item: {id: 2, name: "item name 2", code: "1d4g4"},
      children: [{
        item: {id: 3, name: "item name 2", code: "1d4g4"},
        children:[
          {item: {id: 4, name: "item name 2", code: "1d4g4"}, children: []},
          {item: {id: 4, name: "item name 2", code: "1d4g4"}, children: []},
          {item: {id: 4, name: "item name 2", code: "1d4g4"}, children: []},
        ]
      }]
    }]
  }]
}];

console.log(flatten(data));