最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

TypeScript實(shí)現(xiàn)字符串轉(zhuǎn)樹結(jié)構(gòu)的方法詳解

 更新時(shí)間:2022年09月26日 08:52:25   作者:神奇的程序員  
有一個(gè)多行字符串,每行開頭會(huì)用空格來表示它的層級(jí)關(guān)系,每間隔一層它的空格總數(shù)為2,如何將它轉(zhuǎn)為json格式的樹型數(shù)據(jù)?本文就跟大家分享下這個(gè)算法

前言

有一個(gè)多行字符串,每行開頭會(huì)用空格來表示它的層級(jí)關(guān)系,每間隔一層它的空格總數(shù)為2,如何將它轉(zhuǎn)為json格式的樹型數(shù)據(jù)?本文就跟大家分享下這個(gè)算法,歡迎各位感興趣的開發(fā)者閱讀本文。

例如有一個(gè)字符串:

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

將其轉(zhuǎn)換為有層次結(jié)構(gòu)的json數(shù)據(jù)后為:

{
    "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"
                }
            ]
        }
    ]
}

思路分析

乍一看,要對(duì)字符串進(jìn)行處理,好像沒有什么比較好的方法,理不出頭緒。當(dāng)我們遇到這種直接從數(shù)據(jù)結(jié)構(gòu)出發(fā)想不出辦法的問題時(shí),這時(shí)可能就要換個(gè)思路了,能否將它轉(zhuǎn)換為另一種數(shù)據(jù)結(jié)構(gòu)呢?

審題后發(fā)現(xiàn),我們需要的數(shù)據(jù)元素在字符串中總是獨(dú)占一行的,那么我們就要對(duì)每一行進(jìn)行處理,此時(shí)最好的方式就是將它切割成數(shù)組。

那么,我們就以換行符作為切割點(diǎn)來構(gòu)造數(shù)組,如下所示:

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

觀察數(shù)組中的每個(gè)元素后,我們發(fā)現(xiàn)最頂層的數(shù)據(jù)開頭無空格,每間隔一層,開頭就會(huì)多兩個(gè)空格。按照從前往后的順序依次讀取數(shù)據(jù),將后一個(gè)數(shù)據(jù)與其之前的數(shù)據(jù)進(jìn)行比較,進(jìn)而確定他們之間的層次關(guān)系。

分析到這里,相信很多開發(fā)者已經(jīng)看出了這個(gè)比較方式滿足了**“后入先出”**原則,因此,我們可以用棧來解決這個(gè)問題,如下所示:

  • 準(zhǔn)備2個(gè)棧,一個(gè)用于存放每層的字符串,另一個(gè)用于存放每層的空格數(shù)
  • 默認(rèn)將root入棧,將它的空格數(shù)定為-1

接下來,我們將每個(gè)元素逐一入棧,分析下它的過程。如下圖所示,我們列舉了部分元素的入棧比對(duì)過程,通過觀察后,總結(jié)出了如下幾條規(guī)律。

獲取入棧元素的空格總數(shù)

獲取棧頂(deepStack)元素,判斷入棧元素的空格總數(shù)是否大于棧頂元素。

  • 滿足條件則獲取strStack的棧頂元素,將入棧元素元素放入它的子級(jí)
  • 否則,將兩個(gè)棧的元素依次出棧。直至入棧元素的空格總數(shù)比deepStack的棧頂元素大,獲取strStack的棧頂元素,將入棧元素元素放入它的子級(jí)

將入棧元素以及它的空格總數(shù)分別放入對(duì)應(yīng)的棧中

直至所有元素都入棧比對(duì)完成,此問題得到解決

注意:為了讓讀者更直觀的看出規(guī)律,strStack棧中的元素用字符串直接代替了,實(shí)際上棧中存儲(chǔ)的數(shù)據(jù)是一個(gè)對(duì)象,該對(duì)象包含了name屬性和children屬性。當(dāng)前入棧元素也會(huì)構(gòu)造成一個(gè)對(duì)象,得出棧頂元素(deepStack)與入棧元素空格總數(shù)的比對(duì)結(jié)果后,會(huì)將入棧元素對(duì)象放進(jìn)棧頂元素(strStack)的children中。

實(shí)現(xiàn)代碼

經(jīng)過上面的分析,我們已經(jīng)得出了完整的實(shí)現(xiàn)思路,接下來我們來看下代碼的實(shí)現(xiàn)。

/**
 * 字符串轉(zhuǎn)樹結(jié)構(gòu)
 * @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;
    // 獲取空格總數(shù)
    const len = str.lastIndexOf(" ") + 1;
    str = str.replace(/\s/g, "");
    const curObj = { name: str };

    // 尋找當(dāng)前入棧元素的父層級(jí)
    while (len <= deepStack.peek()) {
      deepStack.pop();
      strStack.pop();
    }
    const stackTop: nodeObj = strStack.peek();
    stackTop.children
      ? stackTop.children.push(curObj)
      : (stackTop.children = [curObj]);

    // 元素入棧,繼續(xù)下一輪的比對(duì)
    strStack.push(curObj);
    deepStack.push(len);
  }

  return json;
}

注意:上述代碼中聲明了一個(gè)自定義類型nodeObj以及一個(gè)自定義類Stack,完整代碼請(qǐng)?jiān)谑纠a中查看。

最后,我們將開頭的例子代入上述代碼中,校驗(yàn)下它能否正確解決問題。

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

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

示例代碼

本文用到的代碼完整版請(qǐng)移步:

DataConversion.ts

DataConversion-test.ts

到此這篇關(guān)于TypeScript實(shí)現(xiàn)字符串轉(zhuǎn)樹結(jié)構(gòu)的方法詳解的文章就介紹到這了,更多相關(guān)TypeScript字符串轉(zhuǎn)樹結(jié)構(gòu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 小程序自定義tabBar組件封裝

    小程序自定義tabBar組件封裝

    這篇文章主要為大家詳細(xì)介紹了小程序自定義tabBar組件封裝,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 一文詳解JavaScript中的事件循環(huán)(event?loop)機(jī)制

    一文詳解JavaScript中的事件循環(huán)(event?loop)機(jī)制

    JavaScript中的事件循環(huán)(Event?Loop)是一種重要的機(jī)制,用于管理異步代碼的執(zhí)行,它確保?JavaScript?單線程環(huán)境中的任務(wù)按照正確的順序執(zhí)行,同時(shí)允許異步操作如定時(shí)器、網(wǎng)絡(luò)請(qǐng)求和事件處理,本將給大家詳細(xì)的介紹一下JavaScript事件循環(huán)機(jī)制,感興趣的朋友可以參考下
    2023-12-12
  • JS基于Location實(shí)現(xiàn)訪問Url、重定向及刷新頁面的方法分析

    JS基于Location實(shí)現(xiàn)訪問Url、重定向及刷新頁面的方法分析

    這篇文章主要介紹了JS基于Location實(shí)現(xiàn)訪問Url、重定向及刷新頁面的方法,結(jié)合實(shí)例形式分析了javascript使用Location進(jìn)行URL訪問、重定向、頁面刷新等操作相關(guān)原理、操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2018-12-12
  • 使用JavaScript實(shí)現(xiàn)一個(gè)簡(jiǎn)單的哈希映射功能

    使用JavaScript實(shí)現(xiàn)一個(gè)簡(jiǎn)單的哈希映射功能

    哈希表大家應(yīng)該都經(jīng)常用到吧,那么大家有沒有想過哈希表是怎么實(shí)現(xiàn)的呢,本文我們就來從一道簡(jiǎn)單的題目來了解一下哈希表的簡(jiǎn)單原理和實(shí)現(xiàn)吧
    2024-02-02
  • JavaScript判斷瀏覽器版本的方法

    JavaScript判斷瀏覽器版本的方法

    這篇文章主要介紹了JavaScript判斷瀏覽器版本的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • JavaScript實(shí)現(xiàn)文件下載的14種方法總結(jié)大全

    JavaScript實(shí)現(xiàn)文件下載的14種方法總結(jié)大全

    在JavaScript中實(shí)現(xiàn)文件下載的功能可以通過多種方式實(shí)現(xiàn),這篇文章主要給大家介紹了關(guān)于JavaScript實(shí)現(xiàn)文件下載的14種方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • Javascript 阻止javascript事件冒泡,獲取控件ID值

    Javascript 阻止javascript事件冒泡,獲取控件ID值

    Javascript學(xué)習(xí)日記-阻止javascript事件冒泡,獲取控件ID值
    2009-06-06
  • js判斷手機(jī)瀏覽器操作系統(tǒng)和微信瀏覽器的方法

    js判斷手機(jī)瀏覽器操作系統(tǒng)和微信瀏覽器的方法

    做手機(jī)端的前端開發(fā),少不了對(duì)手機(jī)平臺(tái)的判斷。如,對(duì)于app下載,就要判斷在Android平臺(tái)下就顯示Android下載提示;在iOS平臺(tái)下就顯示iOS下載提示
    2016-04-04
  • JavaScript中的await函數(shù)使用小結(jié)

    JavaScript中的await函數(shù)使用小結(jié)

    async 函數(shù)是 AsyncFunction 構(gòu)造函數(shù)的實(shí)例,并且其中允許使用 await 關(guān)鍵字,async 和 await 關(guān)鍵字讓我們可以用一種更簡(jiǎn)潔的方式寫出基于 Promise 的異步行為,而無需刻意地鏈?zhǔn)秸{(diào)用 promise,這篇文章主要介紹了JavaScript中的await,需要的朋友可以參考下
    2024-01-01
  • javascript中call,apply,bind函數(shù)用法示例

    javascript中call,apply,bind函數(shù)用法示例

    這篇文章主要介紹了javascript中call,apply,bind函數(shù)用法,結(jié)合實(shí)例形式分析了call,apply,bind函數(shù)的功能、使用方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2016-12-12

最新評(píng)論

扬中市| 水城县| 宁安市| 文山县| 韶关市| 栾城县| 旬阳县| 郸城县| 布拖县| 大石桥市| 台北市| 平度市| 山丹县| 定西市| 洛宁县| 镇原县| 日土县| 建平县| 凤城市| 正镶白旗| 进贤县| 扬州市| 无棣县| 靖边县| 镇赉县| 东宁县| 逊克县| 铅山县| 宜昌市| 保亭| 徐州市| 浮梁县| 安庆市| 宜阳县| 阜阳市| 望都县| 城固县| 贡觉县| 天等县| 高雄县| 墨脱县|