前言

有一个多行字符串,每行开头会用空格来表示它的层级关系,每间隔一层它的空格总数为2,如何将它转为json格式的树型数据?本文就跟大家分享下这个算法,欢迎各位感兴趣的开发者阅读本文。

例如有一个字符串:

const text = `
Language
  JavaScript
    TypeScript
    NodeJS
  HTML
Server
  DataBase
    MongoDB
System
  Linux
  Window
`;

将其转换为有层次结构的json数据后为:

{
    "name":"root",
    "children":[
        {
            "name":"Language",
            "children":[
                {
                    "name":"JavaScript",
                    "children":[
                        {
                            "name":"TypeScript"
                        },
                        {
                            "name":"NodeJS"
                        }
                    ]
                },
                {
                    "name":"HTML"
                }
            ]
        },
        {
            "name":"Server",
            "children":[
                {
                    "name":"DataBase",
                    "children":[
                        {
                            "name":"MongoDB"
                        }
                    ]
                }
            ]
        },
        {
            "name":"System",
            "children":[
                {
                    "name":"Linux"
                },
                {
                    "name":"Window"
                }
            ]
        }
    ]
}

思路分析

乍一看,要对字符串进行处理,好像没有什么比较好的方法,理不出头绪。当我们遇到这种直接从数据结构出发想不出办法的问题时,这时可能就要换个思路了,能否将它转换为另一种数据结构呢?

审题后发现,我们需要的数据元素在字符串中总是独占一行的,那么我们就要对每一行进行处理,此时最好的方式就是将它切割成数组。

那么,我们就以换行符作为切割点来构造数组,如下所示:

[
  "","Language","  JavaScript", "    TypeScript","    NodeJS",   "  HTML","Server","  DataBase","    MongoDB","System","  Linux","  Window",""
]

观察数组中的每个元素后,我们发现最顶层的数据开头无空格,每间隔一层,开头就会多两个空格。按照从前往后的顺序依次读取数据,将后一个数据与其之前的数据进行比较,进而确定他们之间的层次关系。

分析到这里,相信很多开发者已经看出了这个比较方式满足了**“后入先出”**原则,因此,我们可以用栈来解决这个问题,如下所示:

  • 准备2个栈,一个用于存放每层的字符串,另一个用于存放每层的空格数
  • 默认将root入栈,将它的空格数定为-1

接下来,我们将每个元素逐一入栈,分析下它的过程。如下图所示,我们列举了部分元素的入栈比对过程,通过观察后,总结出了如下几条规律。

获取入栈元素的空格总数

获取栈顶(deepStack)元素,判断入栈元素的空格总数是否大于栈顶元素。

  • 满足条件则获取strStack的栈顶元素,将入栈元素元素放入它的子级
  • 否则,将两个栈的元素依次出栈。直至入栈元素的空格总数比deepStack的栈顶元素大,获取strStack的栈顶元素,将入栈元素元素放入它的子级

将入栈元素以及它的空格总数分别放入对应的栈中

直至所有元素都入栈比对完成,此问题得到解决

注意:为了让读者更直观的看出规律,strStack栈中的元素用字符串直接代替了,实际上栈中存储的数据是一个对象,该对象包含了name属性和children属性。当前入栈元素也会构造成一个对象,得出栈顶元素(deepStack)与入栈元素空格总数的比对结果后,会将入栈元素对象放进栈顶元素(strStack)的children中。

实现代码

经过上面的分析,我们已经得出了完整的实现思路,接下来我们来看下代码的实现。

/**
 * 字符串转树结构
 * @param text
 * @constructor
 */
export function DataConversion(text: string): nodeObj {
  const splitArr = text.split("\n");

  const json = { name: "root" };
  const strStack = new Stack();
  const deepStack = new Stack();
  strStack.push(json);
  deepStack.push(-1);

  for (let i = 0; i < splitArr.length; i  ) {
    let str = splitArr[i];
    if (!str) continue;
    // 获取空格总数
    const len = str.lastIndexOf(" ")   1;
    str = str.replace(/\s/g, "");
    const curObj = { name: str };

    // 寻找当前入栈元素的父层级
    while (len <= deepStack.peek()) {
      deepStack.pop();
      strStack.pop();
    }
    const stackTop: nodeObj = strStack.peek();
    stackTop.children
      ? stackTop.children.push(curObj)
      : (stackTop.children = [curObj]);

    // 元素入栈,继续下一轮的比对
    strStack.push(curObj);
    deepStack.push(len);
  }

  return json;
}

注意:上述代码中声明了一个自定义类型nodeObj以及一个自定义类Stack,完整代码请在示例代码中查看。

最后,我们将开头的例子代入上述代码中,校验下它能否正确解决问题。

const text = `
Language
  JavaScript
    TypeScript
    NodeJS
  HTML
Server
  DataBase
    MongoDB
System
  Linux
  Window
`;

const textJSON = DataConversion(text);
console.log(JSON.stringify(textJSON));

示例代码

本文用到的代码完整版请移步:

DataConversion.ts

DataConversion-test.ts

到此这篇关于TypeScript实现字符串转树结构的方法详解的文章就介绍到这了,更多相关TypeScript字符串转树结构内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

TypeScript实现字符串转树结构的方法详解的更多相关文章

  1. 简单总结JavaScript中的String字符串类型

    就像其他语言那样,js中的字符串类型可以表示一串字符,由双引号包住,这里简单总结JavaScript中的String字符串类型的一些基础知识

  2. iOS中字符串换行的实现方法

    大家应该都有所体会,单行字符数过多会影响美观,所以下面这篇文章主要给大家介绍了关于iOS中字符串换行的实现方法,文中通过图文介绍的非常详细,需要的朋友可以参考下

  3. php获取指定数量随机字符串的方法

    这篇文章主要介绍了php获取指定数量随机字符串的方法,涉及php针对数组的遍历及字符串运算相关操作技巧,需要的朋友可以参考下

  4. 使用typescript类型实现ThreeSum

    这篇文章主要介绍了使用typescript类型实现ThreeSum,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以一下,希望对你学习又是帮助

  5.  typeScript入门基础介绍

    这篇文章主要介绍了 typeScript入门基础,TypeScript 是由微软开发的开源、跨平台的编程语言,是 javaScript 的超集,最终被编译为 javaScript代码。常常被简称为TS支持JS、ES语法,下文将继续其他基础介绍,需要的朋友可以参考一下

  6. 基于jQuery对象和DOM对象和字符串之间的转化实例

    下面小编就为大家带来一篇基于jQuery对象和DOM对象和字符串之间的转化实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. typescript返回值类型和参数类型的具体使用

    本文主要介绍了typescript返回值类型和参数类型的具体使用文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  8. 详解PHP用substr函数截取字符串中的某部分

    这篇文章主要介绍了详解PHP用substr函数截取字符串中的某部分,非常具有实用价值,需要的朋友可以参考下。

  9. Python格式化输出字符串的五种方法总结

    Python语言有许多优点,常用于不同的领域,如数据科学、web开发、自动化运维等。本文将学习如何使用字符串中内置的方法来格式化字符串,感兴趣的可以了解一下

  10. Javascript新手入门之字符串拼接与变量的应用

    这篇文章主要给大家介绍了关于Javascript新手入门之字符串拼接与变量应用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部