文档章节

json树状结构的生成

BryanYang
 BryanYang
发布于 2017/11/10 11:41
字数 380
阅读 677
收藏 0
Js

数据库存储结构为平铺的结构:

[
{id:1 , parentId: 0, name: '', level: 0},
{id:2 , parentId: 0, name: '', level: 0},
{id:3 , parentId: 2, name: '', level: 1},
{id:4 , parentId: 2, name: '', level: 1},
{id:5 , parentId: 4, name: '', level: 2},
]


需要转换成树状结构:

{
	children:[
		{
			id: 1,
			name: ''
		},
		{
			id: 2,
			name: '',
			children: [
				{
					id: 3
				},
				{
					id: 4,
					children: [
						{
							id: 5
						}
					]
				}
			]
		},
	]
}

 

算法如下:

const setPath = (parent, arr) => {
  const children = arr.filter(item => item.parentId === parent.id);
  children.forEach((child, i) => {
    child.path = [ ...parent.path, i ];
    setPath(child, arr);
  });
  const myfn = path => {
    return path.map(p => `children[${p}]`).join('.');
  };
  const obj = {};

  return fn => {
    if (!fn) fn = myfn;
    arr = arr.filter(item => item.path !== undefined);
    arr.sort((a, b) => {
      return a.path.length - b.path.length;
    });
    arr.forEach(item => {
      _.set(obj, fn(item.path), item);
    });

    return obj;
  };
};


const res = yield dao.query({ solutionId }); // 从数据库拿到数据平铺的结构
generateMethod=undefined 一般情况下不用传生成方法
//如果有需要,比如只要二级结构,不需要到3级别,那么改变generateMethod即可
/*
generateMethod = path => {
      if (path.length === 2) return 'nouse';
      return path.map(p => `children[${p}]`).join('.');
}
*/
const tree = setPath({ id: 0, path: [] }, res)(generateMethod);

树既然生成了,如何通过给定的叶子节点拿到剪修过的树。树的分支只包含到给定的叶子,其余的分支修剪掉。

const shake = (tree, fn) => {
  const arr = [];
  const path = [];
  const a = {};
  function find(node, path) {
    if (node.children) {
      node.children.forEach((child, i) => find(child, [ ...path, i ]));
    } else {
      if (fn(node)) {
        arr.push(path);
      }
    }
  }
  function deleteNullNode(tree) {
    if (tree.children) {
      tree.children = tree.children.filter(c => c);
      tree.children.forEach(c => deleteNullNode(c));
    }
  }
  find(tree, path);
  arr.forEach(p => {
    for (let i = 1; i <= p.length; i++) {
      const _p = p.slice(0, i).map(c => `children[${c}]`).join('.');
      if (_.has(a, _p)) {
        continue;
      }
      _.set(a, _p, _.omit(_.get(tree, _p), 'children'));
    }
  });
  deleteNullNode(a);
  return a;
};

使用:

shake(tree, leaf => leaf.id == 5 )

 

算法还有很多改进的地方,有些内置的处理需要抽象。后续再更新。

© 著作权归作者所有

下一篇: js文字水印
BryanYang
粉丝 16
博文 165
码字总数 52036
作品 0
石景山
程序员
私信 提问
加载中

评论(0)

Java在后台怎么把Json数据转成Json树状结构,新手求代码。谢谢

之前,利用拼接数据。上网浏览了一些帖子,发现拼接起来很难,并且,很麻烦。 所以,决定改成树状结构。求大神为小弟上代码,谢谢。 原Json数据 转成 Json树状结构后:

金叁胖
2015/10/13
4.1K
3
服务器端物理实现(三)

服务器端物理主需要考虑3个问题: unity客户端中障碍物信息的导出 服务器上物理引擎broadphase的解决方案 服务器端物理的显示渲染 unity客户端可以做一个通用的GameObject Component 导出工具...

李勇2
2016/06/16
325
0
JsonFromTree 树状结构导出到JSON数据的工具

如果有一个配置文件里存储一些简单的配置 例如: x=1 y=2 那么大可直接存储在文件中读取到内存中的一张表中。 可是存储一张树状结构数据,例如一个带有深层菜单项的数据结构如何存储到配置文件...

quanwei9958
2015/12/09
90
0
NUTZ-ONEKEY 2.0 发布,新增微信接入示例

NUTZ-ONEKEY 2.0 发布了,NUTZ一键脚手架。 仓库 目标 提供开箱即用的企业级开发平台 提供企业开发中常见的组件和交互示例 提供高度复用的业务基类 提供各种超高体验的前端交互组件 ... 功能...

Kerbores
2016/09/07
1.4K
12
NUTZ 框架下的企业级项目脚手架--NUTZ-ONEKEY

NUTZ-ONEKEY NUTZ一键脚手架 概述 github地址 https://github.com/Kerbores/NUTZ-ONEKEY 仓库 <repositories> 目标 提供开箱即用的企业级开发平台 提供企业开发中常见的组件和交互示例 提供高...

Kerbores
2016/06/30
4K
6

没有更多内容

加载失败,请刷新页面

加载更多

类和对象

创建对象的几种方式: 1:new创建对象。会增加对象之间的耦合度。不推荐使用。 2:使用反射机制创建对象。Class类的newInstance方法,或者使用Constructor类的newInstance方法。 3:使用对象...

学啥子算法
3分钟前
23
0
你真的会创建一个线程吗?

在文章开始之前先看一个问题,下图几种创建线程方式分别是什么,它们之间的区别和联系是什么? 如果可以轻松回答,那么本文对你来说过于基础,不用往下看啦,如果还有所迷惑,那就和Nauyus一...

JAVA一方
7分钟前
28
0
【已解决】SQL SERVER2008 连接不了本地数据引擎

问题:【已解决】SQL SERVER2008 连接不了本地数据引擎 不知道你有没有遇到过这种情况,当装完 sql server2008之后,然后用 *SQL Server身份验证* 或者 *window身份验证* 访问本地数据库的时...

wanguanrong
8分钟前
14
0
StringTokenizer类

StringTokenizer类:根据自定义字符为分界符进行拆分,并将结果进行封装提供对应方法进行遍历取值,StringTokenizer方法不区分标识符、数和带引号的字符串,它也不识别并跳过注释;该方法用途...

lianbang_W
8分钟前
7
0
自媒体爆文抓取工具有哪些?分享3款爆文工具!

做自媒体运营每天都要持续的创作内容进行输出,这是非常头疼的,不是每一天都会有灵感,有时候就算看再多的素材也没法激发灵感。这时候就需要借助一些同领域做得比较的内容做参考。那么快速地...

易撰自媒体工具
20分钟前
53
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部