当前位置: 首页 > 知识库问答 >
问题:

javascript - 多个树形结构数组如何合并为一个树结构?

诸葛卜霸
2023-04-26

题目描述

[
    [{
        "folderId": null,
        "folderName": "测试",
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": []
    }],
    [{
        "folderId": null,
        "folderName": "测试",
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": []
    }],
    [{
        "folderId": null,
        "folderName": "测试",
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": [{
            "folderId": null,
            "folderName": "第二层",
            "parentId": null,
            "parentName": "测试",
            "fileList": [],
            "children": []
        }]
    }],
    [{
        "folderId": null,
        "folderName": "测试",
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": [{
            "folderId": null,
            "folderName": "第二层",
            "parentId": null,
            "parentName": "测试",
            "fileList": [],
            "children": []
        }]
    }],
    [{
        "folderId": null,
        "folderName": "测试",
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": [{
            "folderId": null,
            "folderName": "第二层",
            "parentId": null,
            "parentName": "测试",
            "fileList": [],
            "children": [{
                "folderId": null,
                "folderName": "第三层",
                "parentId": null,
                "parentName": "第二层",
                "fileList": [],
                "children": []
            }]
        }]
    }],
    [{
        "folderId": null,
        "folderName": "测试",
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": [{
            "folderId": null,
            "folderName": "第二层",
            "parentId": null,
            "parentName": "测试",
            "fileList": [],
            "children": [{
                "folderId": null,
                "folderName": "测试",
                "parentId": null,
                "parentName": "第二层",
                "fileList": [],
                "children": []
            }]
        }]
    }]
]

希望将上面数组用js转化成下面格式,请问如何实现呢

[
  {
    "folderId": null,
    "folderName": "测试",
    "parentId": null,
    "parentName": null,
    "fileList": [],
    "children": [
      {
        "folderId": null,
        "folderName": "第二层",
        "parentId": null,
        "parentName": "测试",
        "fileList": [],
        "children": [
          {
            "folderId": null,
            "folderName": "第三层",
            "parentId": null,
            "parentName": "第二层",
            "fileList": [],
            "children": []
          },
          {
            "folderId": null,
            "folderName": "测试",
            "parentId": null,
            "parentName": "第二层",
            "fileList": [],
            "children": []
          }
        ]
      }
    ]
  }
]

共有5个答案

郎鸿雪
2023-04-26
let arr = [
    [{
        "folderId": null,
        "folderName": 1,
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": []
    }],
    [{
        "folderId": null,
        "folderName": 1,
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": []
    }],
    [{
        "folderId": null,
        "folderName": 1,
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": [{
            "folderId": null,
            "folderName": 2,
            "parentId": null,
            "parentName": 1,
            "fileList": [],
            "children": []
        }]
    }],
    [{
        "folderId": null,
        "folderName": 1,
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": [{
            "folderId": null,
            "folderName": 2,
            "parentId": null,
            "parentName": 1,
            "fileList": [],
            "children": []
        }]
    }],
    [{
        "folderId": null,
        "folderName": 1,
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": [{
            "folderId": null,
            "folderName": 2,
            "parentId": null,
            "parentName": 1,
            "fileList": [],
            "children": [{
                "folderId": null,
                "folderName": 3,
                "parentId": null,
                "parentName": 2,
                "fileList": [],
                "children": []
            }]
        }]
    }],
    [{
        "folderId": null,
        "folderName": 1,
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": [{
            "folderId": null,
            "folderName": 2,
            "parentId": null,
            "parentName": 1,
            "fileList": [],
            "children": [{
                "folderId": null,
                "folderName": 4,
                "parentId": null,
                "parentName": 2,
                "fileList": [],
                "children": []
            }]
        }]
    }]
]



function treeTotree(arr,root, id, pid) {


    let newArr = []
    //数组展开
    arr = arr.flat(Infinity)
    function flat(arr) {
        arr.forEach(element => {
            if (element.children.length !== 0) {
                flat(element.children)
                element.children = null
            } else {
                newArr.push(element)
            }
        });
    }
    //数组去重
    function unique(arr){
        const newArr = [];
        for (const t of arr) {
          // 检查缓存中是否已经存在
          if (
            newArr.find(
              (c) =>
                c[id] === t[id] &&
                c[pid] === t[pid]
            )
          ) {
            // 已经存在说明以前记录过,现在这个就是多余的,直接忽略
            continue;
          }
          // 不存在就说明以前没遇到过,把它记录下来
          newArr.push(t);
        }

        // 记录结果就是过滤后的结果
        return newArr;
    }

    flat(arr)
    newArr =  unique(newArr)
    
    // console.log(newArr);

    //处理为目标结构
    function treeToTree(items, root, _id, _pid) {
        const result = [];   // 存放结果集
        const itemMap = {};  // 
        for (const item of items) {
          const id = item[_id];
          const pid = item[_pid];
      
          if (!itemMap[id]) {
            itemMap[id] = {
              children: [],
            }
          }
      
          itemMap[id] = {
            ...item,
            children: itemMap[id]['children']
          }
      
          const treeItem =  itemMap[id];
      
          if (pid === root) {
            result.push(treeItem);
          } else {
            if (!itemMap[pid]) {
              itemMap[pid] = {
                children: [],
              }
            }
            itemMap[pid].children.push(treeItem)
          }
      
        }
        return result;
      }

    return treeToTree(newArr, root, id, pid)
}


console.log(treeTotree(arr,null,'folderName','parentName'));

你的数据有问题, 会出现循环, 就是folderName为测试, 会出现循环, 所以我改了你的数据. 这是个通用方法, 适合大多数的树转树或者数组转树, 参数分别为原始数据, 输出根目标标识, id(父),pid(子)

吕华彩
2023-04-26
function transform(target, source) {
    var ret = source || [];
    for (var i = 0; i < target.length; ++i) {
        var obj, item = target[i];
        find: {
            for (var j = 0; j < ret.length; ++j) {
                obj = ret[j];
                if (obj.folderName === item.folderName) break find;
            }
            obj = ret[ret.length] = {};
            for (var key in item) obj[key] = item[key];
            obj.children.length = 0;
        }
        transform(item.children, obj.children);
    }
    return ret;
}
function flatten(arr) {
    var ret = [];
    var stack = arr.slice();
    while (stack.length) {
        var top = stack.pop();
        if (top instanceof Array) {
            stack.push.apply(stack, top);
        } else {
            ret.unshift(top);
        }
    }
    return ret;
}
var list = [
    [{
        "folderId": null,
        "folderName": "测试",
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": []
    }],
    [{
        "folderId": null,
        "folderName": "测试",
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": []
    }],
    [{
        "folderId": null,
        "folderName": "测试",
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": [{
            "folderId": null,
            "folderName": "第二层",
            "parentId": null,
            "parentName": "测试",
            "fileList": [],
            "children": []
        }]
    }],
    [{
        "folderId": null,
        "folderName": "测试",
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": [{
            "folderId": null,
            "folderName": "第二层",
            "parentId": null,
            "parentName": "测试",
            "fileList": [],
            "children": []
        }]
    }],
    [{
        "folderId": null,
        "folderName": "测试",
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": [{
            "folderId": null,
            "folderName": "第二层",
            "parentId": null,
            "parentName": "测试",
            "fileList": [],
            "children": [{
                "folderId": null,
                "folderName": "第三层",
                "parentId": null,
                "parentName": "第二层",
                "fileList": [],
                "children": []
            }]
        }]
    }],
    [{
        "folderId": null,
        "folderName": "测试",
        "parentId": null,
        "parentName": null,
        "fileList": [],
        "children": [{
            "folderId": null,
            "folderName": "第二层",
            "parentId": null,
            "parentName": "测试",
            "fileList": [],
            "children": [{
                "folderId": null,
                "folderName": "测试",
                "parentId": null,
                "parentName": "第二层",
                "fileList": [],
                "children": []
            }]
        }]
    }]
];
console.log(transform(flatten(list)));
公良扬
2023-04-26
$(function() {
    var list = [
        {
            "folderId": null,
            "folderName": "测试",
            "parentId": null,
            "parentName": null,
            "fileList": [],
            "children": [
                {
                    "folderId": null,
                    "folderName": "第二层",
                    "parentId": null,
                    "parentName": "测试",
                    "fileList": [],
                    "children": [
                        {
                            "folderId": null,
                            "folderName": "第三层",
                            "parentId": null,
                            "parentName": "第二层",
                            "fileList": [],
                            "children": []
                        },
                        {
                            "folderId": null,
                            "folderName": "测试",
                            "parentId": null,
                            "parentName": "第二层",
                            "fileList": [],
                            "children": []
                        }
                    ]
                }
            ]
        }
    ]
    debugger;
    console.log(transformArray(list))
});


function transformArray(arr) {
    const result = [];

    function traverse(node, target) {
        target.push({
            folderId: node.folderId,
            folderName: node.folderName,
            parentId: node.parentId,
            parentName: node.parentName,
            fileList: node.fileList,
            children: []
        });

        if (node.children.length > 0) {
            for (let i = 0; i < node.children.length; i++) {
                traverse(node.children[i], target[target.length - 1].children);
            }
        }
    }

    traverse(arr[0], result);

    return result;
}

image.png

郏志学
2023-04-26

如果你确定每个数组里面,只包含一个元素(不算子元素),可以用一种简单的方法解决

let str=JSON.stringify(arr) //把你的数组转成json字符串

str=str.replaceAll('[{',"{") //替换字符
str=str.replaceAll('}]',"}")

let obj=JSON.parse(str) //把字符串还原为对象
console.log(obj)
索曾琪
2023-04-26

你可以用递归来实现:

const data = [
  // 这里是你给出的原始数据
];

function mergeTrees(trees) {
  const result = {};
  const uniqueKey = 'folderName';

  function mergeNode(node, resultNode) {
    if (!resultNode.children) {
      resultNode.children = [];
    }

    const existingNode = resultNode.children.find(
      (child) => child[uniqueKey] === node[uniqueKey]
    );

    if (existingNode) {
      node.children.forEach((child) => mergeNode(child, existingNode));
    } else {
      resultNode.children.push(node);
    }
  }

  trees.forEach((tree) => {
    tree.forEach((node) => {
      mergeNode(node, result);
    });
  });

  return result.children;
}

const mergedTree = mergeTrees(data);
console.log(mergedTree);
 类似资料:
  • 扁平数组的结构如上,每个目录下都可以添加数据 如何将这个数组转成树形的结构啊,转成如下的形式 目录层级的name就取对应的 xxxLevelStr

  • 背景:基于Element UI 开发的项目,使用到了Tree树型控件 需求:页面有一个tree控件(可选择)如图 这个控件在切换月份的时候可能存在二级节点下有新增的节点或者减少的节点, 如果 ‘一级2’被全部中了,那么切换其他月份如果 ‘一级2’节点下有新增的节点也要勾选上。 树的深度不确定(后端返的),数据量大的时候遍历判断会影响性能,求问各位大佬 有什么比较好的办法处理吗 找出两颗树的差异的节

  • 树形结构组件。 Usage 全部引入 import { TreeView } from 'beeshell'; 按需引入 import { TreeView } from 'beeshell/dist/components/TreeView'; Examples Code 详细 Code ```js import { TreeView } from 'beeshell'; const nest

  • 我在这个结构中有一个数组,其中包含用户元素,每个用户都可以与另一个用户相关 我只想让每个用户都包含其子用户的用户树成为一棵树。 ) 这里user4在user3用户中,user3在user2用户中包含其用户,user2在user1用户中包含其用户,user5在user1用户中包含其用户 所需的结构类似于

  • 树形结构在软件中随处可见,例如操作系统中的目录结构、应用软件中的菜单、办公系统中的公司组织结构等等,如何运用面向对象的方式来处理这种树形结构是组合模式需要解决的问题,组合模式通过一种巧妙的设计方案使得用户可以一致性地处理整个树形结构或者树形结构的一部分,也可以一致性地处理树形结构中的叶子节点(不包含子节点的节点)和容器节点(包含子节点的节点)。下面将学习这种用于处理树形结构的组合模式。   11.

  • 有个以下格式的省市区数组对象: 请问如何用Ts变为以下格式的二维数组?