我无法使用某个映射转换字符串。我想要转换的字符串如下:
输入
$B$O$TT$O$$KK$$Z$HH$$U$PP$$QQ$U$Z$B$
可以更好地看作以下内容(非常接近HTML):
$B
$O
$TT$
O$
$K
K$
$Z
$HH$
$U
$PP$
$QQ$
U$
Z$
B$
我的目标是将其转化为以下内容:
预期结果
{
"v": "B",
"chld": [
{
"v": "O",
"chld": [
{
"v": "T"
}
]
},
{
"v": "K"
},
{
"v": "Z",
"chld": [
{
"v": "H"
},
{
"v": "U",
"chld": [
{
"v": "P"
},
{
"v": "Q"
}
]
}
]
}
]
}
我得到的地方:
function transform(contentString, currentObj, currentChld) {
let closeOpen = {
open: /\$[A-Z]/i,
closed: /[A-Z]\$/i
}
if (!contentString.length) {
return currentObj
}
let currentSlice = contentString.slice(0, 2)
let newString = contentString.substring(2)
//See if tag is open, for example $A is open, A$ is closed
if (currentSlice.match(closeOpen['open'])){
currentObj = {v: currentSlice[1]}
currentObj.chld = []
return transform(newString, currentObj , currentChld)
}
}
似乎递归并不是很有效。解决方案不一定要递归。如果有更简单的东西也没关系!我希望得到上面的预期结果。有人可以帮忙吗?最简单的解决方案是最好的!
编辑:是的标签只有一个字母,仅限于[A-Z]
答案 0 :(得分:4)
我迟到了,但是一个简单的基于堆栈的appraoch工作得很好。
export class ApiService {
private selectedCode = new Subject<any>(); // holds reference to clicked item in list
codeSelected= this.selectedCode.asObservable(); // subscribe
constructor(private http: HttpClient) {}
getCodes() {
return this.http.get('http://localhost:58561/api/codes');
}
postCode(code) {
this.http.post('http://localhost:58561/api/codes', code).subscribe(res => {
console.log(res)
})
}
selectCode(code) {
this.selectedCode.next(code)
}
}
答案 1 :(得分:1)
您可以编写一个PEG.js解析器来为您创建树:
class Node {
constructor (tag, children = []) {
this.v = tag;
if (children.length > 0) {
this.chld = children;
}
}
toString () {
return '$' + this.v + (this.chld || []).join('') + this.v + '$'
}
}
let parser = PEG.buildParser(`
Expression = open:Open children:Expression * close:Close {
var object = new Node(open, children);
if (open !== close) {
return expected('"' + object + '"');
}
return object
}
Open = "$" tag:Tag { return tag }
Close = close:Tag "$" { return close }
Tag = [A-Za-z]
`, { cache: true });
let tree = parser.parse('$B$O$TT$O$$KK$$Z$HH$$U$PP$$QQ$U$Z$B$');
console.log(tree);
try {
parser.parse('$B$O$TT$$U$PP$V$O$B$');
} catch (error) {
console.log(error.message);
}
.as-console-wrapper{max-height:100%!important}
<script src="https://cdnjs.cloudflare.com/ajax/libs/pegjs/0.9.0/peg.min.js"></script>
请注意,在版本0.10中,根据documentation,该方法已从peg.buildParser()
更改为peg.generate()
。
答案 2 :(得分:0)
这是一个将结构构建为字符串的简单循环,然后使用JSON解析器将其转换为对象:
const ip = "$B$O$TT$O$$KK$$Z$HH$$U$PP$$QQ$U$Z$B$"
function transform(contentString) {
let op = "";
for(var i = 0; i < contentString.length - 3; i += 2) {
if (contentString[i] === "$") {
op += `{"v":"${contentString[i+1]}"`;
if (contentString[i+2] === "$") {
op += `,"chld":[`;
}
} else {
op += "}";
if (contentString[i+2] === "$") {
op += ",";
} else {
op += "]";
}
}
}
return JSON.parse(op + "}");
}
console.log(transform(ip));
注意没有语法检查;代码假定输入字符串是格式良好的结构。