Json数据格式实现单词树大数据快速查询
思路:空间换时间,树本身可以方便储存和读取,快速查询
优势:
- json格式的树可以快速在字符串和json格式之间转换
- 通过对象名直接访问子元素跳过遍历子元素,速度极快,经过测试比对象树至少快三倍
- 代码量极少,区区不到100行
- 树本身占用控件较小
脚本JsonTree.ts
/***
*
* █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
* ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
* ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
* ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
* ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
* ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
* ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
* ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
* ░ ░ ░ ░ ░
*
*
* 本代码作者:山水有相逢
* 小号QQ:3179132247
* 《json格式单词树》
*/
import { _decorator,warn } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('JsonTree')
export class JsonTree {
private static _instance: JsonTree = null;
static get instance() {
if (this._instance == null) this._instance = new JsonTree();
return this._instance;
}
/**json数组转json单词树 */
jsonArrToJsonTree(json: Object | any[]): Object {
let outJsonTree: Object = {};
let reg = /^[A-Za-z]+$/;
for (const key in json) {
let wordStr: string = json[key];
if (reg.test(wordStr)) {
this.addWordToTree(outJsonTree, wordStr.toLocaleLowerCase(), "1");
} else {
warn("单词不是纯字母:", wordStr);
}
}
return outJsonTree;
}
/**
* 添加单词进入json树
* @param treeObj json树
* @param word 单词
* @param value 标记单词的值(可以是对象,字符串,数字等)
*/
addWordToTree(treeObj: Object, word: string, value: any) {
let lastObj: Object = treeObj;
for (let index = 0; index < word.length; index++) {
if (!(word[index] in lastObj)) lastObj[word[index]] = {};//如果没有指定键,创建并置空
if (index == word.length - 1) { lastObj[word[index]]["_v"] = value; break; }//如果是单词结尾,填入值
lastObj = lastObj[word[index]];//如果单词未结束,更新当前对象到下一级
}
}
/**
* 从json树移除单词
* @param treeObj json树
* @param word 单词
*/
subWordToTree(treeObj: Object, word: string): boolean {
let lastObj: Object = treeObj;
for (let index = 0; index < word.length; index++) {
if (!lastObj[word[index]]) {//如果没有目标键,移除失败
return false;
}
lastObj = lastObj[word[index]];
}
delete lastObj["_v"];
this.subWordPathToTree(treeObj, word);
return true;
}
/**
* 移除目标单词路径
* @param treeObj json树
* @param word 单词
*/
private subWordPathToTree(treeObj: Object, word: string) {
for (let index = 0; index < word.length; index++) {
let lastObj: Object = treeObj;
for (let index = 0; index < word.length; index++) {
if (!lastObj[word[index]]) break;
if (JSON.stringify(lastObj[word[index]]) == "{}") { delete lastObj[word[index]]; break }
lastObj = lastObj[word[index]];
}
}
}
/**
* 查询单词是否在json单词树中
* @param treeObj 单词json树
* @param word 要查询单词
* @returns true:单词在树中,false:单词不在树中
*/
findWordIsInTree(treeObj: Object, word: string): boolean {
let lastObj: Object = treeObj;
for (let index = 0; index < word.length; index++) {
if (!lastObj[word[index]]) {//如果没有目标键,则未存入单词
return false;
}
lastObj = lastObj[word[index]];
}
return !!lastObj["_v"];
}
}
使用样例
//样例
let jsonObj:Object = [and,about,some,any,add,apple];//单词库
let outTree: Object = JsonTree.instance.jsonArrToJsonTree(jsonObj);//初始化json树
log(“outTree”, outTree);
log(“查询:”,JsonTree.instance.findWordIsInTree(outTree, “about”));
log(“删除:”,JsonTree.instance.subWordToTree(outTree, “about”));
log(“查询:”,JsonTree.instance.findWordIsInTree(outTree, “about”));