简体   繁体   English

如何在JavaScript中将字符串树解析为数组

[英]How to parse string tree into array in JavaScript

Let's say I get an API response that returns a tree-like structure like this: 假设我得到一个API响应,该响应返回一个像这样的树状结构:

"gw43g: (-95.147, 38.5818); " +
"jp987h: (" +
         "bvp7: (-97.450, 30.150); " +
         "7g8oi: (" +
                 "34ilht: (-82.192997, 29.39719); " +
                 "34hb1: (-122.25, 37.47)); " +
         "b238: (-71.0349, 42.2129)); " +
"ao8yh: (-90.147, 42.5818);"

Its a string. 它是一个字符串。

Using JavaScript, I need to turn it into an array like this.. 使用JavaScript,我需要将其变成这样的数组。

["(-95.147, 38.5818)",
  "(bvp7: (-97.450, 30.150); 7g8oi: (...)...)",
  "(-90.147, 42.5818)"]

..such that the innards of each pair of parenthesizes is an array item, no matter many nested parenthesizes are contained in the outermost pair. ..这样,每对括号中的内脏都是一个数组项,无论最外面的一对中是否包含许多嵌套的括号。

I'm not having any luck, so I'm asking your your guy's help. 我没有运气,所以我要问你你的家伙的帮助。 Here's what I've tried. 这是我尝试过的。

function getCoords(str) {
    return str.split(';').map(function(s) {
        return s.substring(s.indexOf('(')+1, s.lastIndexOf(')'));
    });
}

..but that's way wrong. ..但是那是错误的方式。 Feel free to call on any functional toolkits (underscore.js, etc). 随时调用任何功能性工具箱(underscore.js等)。 And no, this is not a homework assignment, it's for a book I'm writing. 不,这不是家庭作业,是我正在写的书。 Thanks for any help! 谢谢你的帮助!

You could use Array.prototype.reduce() like this: 您可以像这样使用Array.prototype.reduce()

 var str = "gw43g: (-95.147, 38.5818); " + "jp987h: (" + "bvp7: (-97.450, 30.150); " + "7g8oi: (" + "34ilht: (-82.192997, 29.39719); " + "34hb1: (-122.25, 37.47)); " + "b238: (-71.0349, 42.2129)); " + "ao8yh: (-90.147, 42.5818);" var cnt = 0; // keep count of opened brackets var result = Array.prototype.reduce.call(str, function(prev, curr) { if (curr === '(' && cnt++ === 0) prev.push(''); if (cnt > 0) prev[prev.length-1] += curr; if (curr === ')') cnt--; return prev; }, []); console.log(result); 

JSFiddle mirror JSF中镜

You should probably use a parser for this, but here's a quick and dirty solution that's kind of like a mini-parser: 您可能应该为此使用解析器,但这是一个快速而肮脏的解决方案,有点像迷你解析器:

var src = "gw43g: (-95.147, 38.5818) .... ";

var re = /(\w+:\s*\()|(\);?)|((?:(?!\w+:\s*\(|\);?).)+)/g;

var output = [];
var match;
var stackCount = 0;

while ((match = re.exec(src)))
{
    if (match[1]) {
        if (stackCount == 0) output.push('');
        stackCount++;
    }
    else if (match[2]) {
        stackCount--;
    }
    output[output.length-1] += match[0];
}
console.log(output);

jsFiddle 的jsfiddle

The regular expression splits tokens into three categories, a stack opener, a stack closer, or neutral. 正则表达式将令牌分为三类:堆栈打开器,堆栈关闭器或中性。 If it finds a stack starter and there is nothing on the stack it adds a new array item, if it finds a closer it brings the stack down by one. 如果找到堆栈启动器,但堆栈上没有任何内容,则添加新的数组项;如果找到更近的数组,则堆栈减少一。 Until the stack is at zero, it will keep appending to the current array item. 在堆栈为零之前,它将继续追加到当前数组项。

I couldn't help it, so I went ahead and just finished the simple parser, so that the string is output as an tree where the root properties are the keys (gw43g), and each either has an X, Y value, or it is a branch on the tree. 我无能为力,所以我继续完成简单的解析器,以便将字符串输出为树,其中根属性是键(gw43g),每个键都有一个X,Y值,或者它是树上的树枝。

function parseBody(str) { 
    // rey: http://rey.gimenez.biz/s/fxd02f
    var re = /\s+|(\w+)\s*:\s*\(|(\);?)|(([\-+]?\s*(?:\d*\.\d*|\d+))\s*,\s*([\-+]?\s*(?:\d*\.\d*|\d+)))/g;

    var output = [];
    var match;
    var newObj;
    var root = { children: { } }
    var branch = root;

    while ((match = re.exec(str)))
    {
        // key and open
        if (match[1]) {
            newObj = { parent: branch, children: { } };
            branch.children[match[1]] = newObj;
            // new stack
            branch = newObj;
        }
        // 
        else if (match[2]) {
            // move up stack
            branch = branch.parent;
        }
        else if (match[3]) {
            branch.X = parseFloat(match[4]);
            branch.Y = parseFloat(match[5]);
        }
    }

    return root;
}

jsFiddle 的jsfiddle

Regular Expression 正则表达式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM