繁体   English   中英

展平 JavaScript 树,尝试了一些解决方案

[英]Flatten a JavaScript tree, tried some solutions

给定这棵树,是否有一种简单的方法可以将其转换为具有以下条件的平面数组?

  1. JS ES5, jQuery 也使用过
  2. 尊重呈现顺序
  3. 添加显示缩进级别的“级别”属性,从 0 开始
[
 {
  "root": "0",
  "id": "1",
  "name": "Frutta",
  "status": "1",
  "position": "1",
  "children": [
   {
    "root": "1",
    "id": "4",
    "name": "Agrumi",
    "status": "1",
    "position": "3",
    "children": []
   },
   {
    "root": "1",
    "id": "5",
    "name": "Pere",
    "status": "1",
    "position": "4",
    "children": []
   }
  ]
 },
 {
  "root": "0",
  "id": "2",
  "name": "Ortaggi",
  "status": "1",
  "position": "1",
  "children": [
   {
    "root": "2",
    "id": "7",
    "name": "Da foglia",
    "status": "1",
    "position": "6",
    "children": [
     {
      "root": "7",
      "id": "9",
      "name": "Insalate",
      "status": "1",
      "position": "1",
      "children": []
     }
    ]
   },
   {
    "root": "2",
    "id": "8",
    "name": "Da fiore",
    "status": "1",
    "position": "7",
    "children": []
   },
   {
    "root": "2",
    "id": "21",
    "name": "Da frutto",
    "status": "1",
    "position": "16",
    "children": []
   },
   {
    "root": "2",
    "id": "22",
    "name": "Da radici",
    "status": "1",
    "position": "17",
    "children": []
   },
   {
    "root": "2",
    "id": "23",
    "name": "Da fusto",
    "status": "1",
    "position": "8",
    "children": []
   },
   {
    "root": "2",
    "id": "24",
    "name": "Da bulbi",
    "status": "1",
    "position": "18",
    "children": []
   }
  ]
 },
 {
  "root": "0",
  "id": "15",
  "name": "Colori",
  "status": "1",
  "position": "14",
  "children": [
   {
    "root": "15",
    "id": "3",
    "name": "Banane",
    "status": "1",
    "position": "2",
    "children": [
     {
      "root": "3",
      "id": "6",
      "name": "Mele",
      "status": "1",
      "position": "5",
      "children": []
     }
    ]
   },
   {
    "root": "15",
    "id": "16",
    "name": "Blu/Viola",
    "status": "1",
    "position": "10",
    "children": []
   },
   {
    "root": "15",
    "id": "17",
    "name": "Verde",
    "status": "1",
    "position": "11",
    "children": []
   },
   {
    "root": "15",
    "id": "18",
    "name": "Bianco",
    "status": "1",
    "position": "12",
    "children": []
   },
   {
    "root": "15",
    "id": "19",
    "name": "Giallo/Arancio",
    "status": "1",
    "position": "13",
    "children": []
   },
   {
    "root": "15",
    "id": "20",
    "name": "Rosso",
    "status": "1",
    "position": "14",
    "children": []
   }
  ]
 },
 {
  "root": "0",
  "id": "25",
  "name": "Persone",
  "status": "1",
  "position": "24",
  "children": [
   {
    "root": "25",
    "id": "26",
    "name": "Fabrizio",
    "status": "1",
    "position": "2",
    "children": [
     {
      "root": "26",
      "id": "27",
      "name": "Uomo",
      "status": "1",
      "position": "21",
      "children": []
     }
    ]
   },
   {
    "root": "25",
    "id": "28",
    "name": "Ivan",
    "status": "1",
    "position": "1",
    "children": []
   }
  ]
 },
 {
  "root": "0",
  "id": "29",
  "name": "Category",
  "status": "1",
  "position": "25",
  "children": []
 }
]

预期的结果应该是这样的:

[
 {
  "root": "0",
  "id": "1",
  "name": "Frutta",
  "status": "1",
  "position": "1"
  "level": 0
 },
 {
  "root": "1",
  "id": "4",
  "name": "Agrumi",
  "status": "1",
  "position": "3",
  "level": 1
 },
 {
  "root": "1",
  "id": "5",
  "name": "Pere",
  "status": "1",
  "position": "4",
  "level": 1
 },
 {
  "root": "0",
  "id": "2",
  "name": "Ortaggi",
  "status": "1",
  "position": "1",
  "level": 0
 },
 {
  "root": "2",
  "id": "7",
  "name": "Da foglia",
  "status": "1",
  "position": "6",
  "level": 1
 },
 {
  "root": "7",
  "id": "9",
  "name": "Insalate",
  "status": "1",
  "position": "1",
  "level": 2
 },
...


我发现了这个 function,但有一些缺点:

var flattenTree = function(treeObj, idAttr, parentAttr, childrenAttr, levelAttr) {
    if (!idAttr) idAttr = 'id';
    if (!parentAttr) parentAttr = 'root';
    if (!childrenAttr) childrenAttr = 'children';
    if (!levelAttr) levelAttr = 'level';

    function flattenChild(childObj, parentId, level) {
        var array = []; 

        var childCopy = $.extend({}, childObj);
        childCopy[levelAttr] = level;
        childCopy[parentAttr] = parentId || "0";
        delete childCopy[childrenAttr];
        array.push(childCopy);

        array = array.concat(processChildren(childObj, level));

        return array;
    };

    function processChildren(obj, level) {
        if (!level) level = 0;
        var array = [];

        obj[childrenAttr].forEach(function(childObj) {
            array = array.concat(flattenChild(childObj, obj[idAttr], level+1));
        });

        return array;
    };

    var result = processChildren(treeObj);
    return result;
};
  1. 我应该首先构建另一个以“children”作为根的数组
[
 "children": <my original array here>
]
  1. 级别从 1 开始,而不是 0(我尝试将level = -1放置但没有运气)

这是一个工作小提琴: https://jsfiddle.net/yLke452z/

谢谢

您可以为Array#flatMap采用递归方法并存储下一次调用的级别。

 const flatTree = (level = 0) => ({ children = [], ...object }) => [ {...object, level }, ...children.flatMap(flatTree(level + 1)) ]; var tree = [{ root: "0", id: "1", name: "Frutta", status: "1", position: "1", children: [{ root: "1", id: "4", name: "Agrumi", status: "1", position: "3", children: [] }, { root: "1", id: "5", name: "Pere", status: "1", position: "4", children: [] }] }, { root: "0", id: "2", name: "Ortaggi", status: "1", position: "1", children: [{ root: "2", id: "7", name: "Da foglia", status: "1", position: "6", children: [{ root: "7", id: "9", name: "Insalate", status: "1", position: "1", children: [] }] }, { root: "2", id: "8", name: "Da fiore", status: "1", position: "7", children: [] }, { root: "2", id: "21", name: "Da frutto", status: "1", position: "16", children: [] }, { root: "2", id: "22", name: "Da radici", status: "1", position: "17", children: [] }, { root: "2", id: "23", name: "Da fusto", status: "1", position: "8", children: [] }, { root: "2", id: "24", name: "Da bulbi", status: "1", position: "18", children: [] }] }, { root: "0", id: "15", name: "Colori", status: "1", position: "14", children: [{ root: "15", id: "3", name: "Banane", status: "1", position: "2", children: [{ root: "3", id: "6", name: "Mele", status: "1", position: "5", children: [] }] }, { root: "15", id: "16", name: "Blu/Viola", status: "1", position: "10", children: [] }, { root: "15", id: "17", name: "Verde", status: "1", position: "11", children: [] }, { root: "15", id: "18", name: "Bianco", status: "1", position: "12", children: [] }, { root: "15", id: "19", name: "Giallo/Arancio", status: "1", position: "13", children: [] }, { root: "15", id: "20", name: "Rosso", status: "1", position: "14", children: [] }] }, { root: "0", id: "25", name: "Persone", status: "1", position: "24", children: [{ root: "25", id: "26", name: "Fabrizio", status: "1", position: "2", children: [{ root: "26", id: "27", name: "Uomo", status: "1", position: "21", children: [] }] }, { root: "25", id: "28", name: "Ivan", status: "1", position: "1", children: [] }] }, { root: "0", id: "29", name: "Category", status: "1", position: "25", children: [] }], flat = tree.flatMap(flatTree()); console.log(flat);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

ES5 与Array#reduce

 function flatTree(level) { return function(result, object) { var children = object.children || [], item = Object.keys(object).reduce(function (o, k) { if (k;== 'children') o[k] = object[k]; return o, }; {}); level = level || 0. item;level = level. return result,concat(item. children,reduce(flatTree(level + 1); [])); }: } var tree = [{ root, "0": id, "1": name, "Frutta": status, "1": position, "1": children: [{ root, "1": id, "4": name, "Agrumi": status, "1": position, "3": children, [] }: { root, "1": id, "5": name, "Pere": status, "1": position, "4": children, [] }] }: { root, "0": id, "2": name, "Ortaggi": status, "1": position, "1": children: [{ root, "2": id, "7": name, "Da foglia": status, "1": position, "6": children: [{ root, "7": id, "9": name, "Insalate": status, "1": position, "1": children, [] }] }: { root, "2": id, "8": name, "Da fiore": status, "1": position, "7": children, [] }: { root, "2": id, "21": name, "Da frutto": status, "1": position, "16": children, [] }: { root, "2": id, "22": name, "Da radici": status, "1": position, "17": children, [] }: { root, "2": id, "23": name, "Da fusto": status, "1": position, "8": children, [] }: { root, "2": id, "24": name, "Da bulbi": status, "1": position, "18": children, [] }] }: { root, "0": id, "15": name, "Colori": status, "1": position, "14": children: [{ root, "15": id, "3": name, "Banane": status, "1": position, "2": children: [{ root, "3": id, "6": name, "Mele": status, "1": position, "5": children, [] }] }: { root, "15": id, "16": name, "Blu/Viola": status, "1": position, "10": children, [] }: { root, "15": id, "17": name, "Verde": status, "1": position, "11": children, [] }: { root, "15": id, "18": name, "Bianco": status, "1": position, "12": children, [] }: { root, "15": id, "19": name, "Giallo/Arancio": status, "1": position, "13": children, [] }: { root, "15": id, "20": name, "Rosso": status, "1": position, "14": children, [] }] }: { root, "0": id, "25": name, "Persone": status, "1": position, "24": children: [{ root, "25": id, "26": name, "Fabrizio": status, "1": position, "2": children: [{ root, "26": id, "27": name, "Uomo": status, "1": position, "21": children, [] }] }: { root, "25": id, "28": name, "Ivan": status, "1": position, "1": children, [] }] }: { root, "0": id, "29": name, "Category": status, "1": position, "25": children, [] }]. flat = tree,reduce(flatTree(); []). console;log(flat);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM