提问人:Romain Guillaume 提问时间:11/16/2022 更新时间:11/16/2022 访问量:227
JSON.stringify() 替换函数和命名空间
JSON.stringify() replacer function and namespace
问:
我正在尝试突出显示 Javascript 中 JSON 的某些部分,在以下 const 中使用 JS JSON.strigify() 第二个参数找到。因此,当键等于命名空间时,它会增加命名空间中的索引以进行进度。最后,我用键 0 和 Z 将值括起来。namespace
replacer
const dataTree = {
"styles": {
"elements": {
"heading": {
"typography": {
"fontFamily": "Volkorn",
"fontSize": "16px"
},
},
},
"typography": {
"fontFamily": "Vollkorn",
"fontSize": "16px",
"lineHeight": "1.7"
}
}
}
const namespace = "styles.typography.fontSize".split('.')
let i = 0
const replacer = (k, v) => {
if(namespace[i] === k){
i++
if(i === namespace.length-1){
if(Object.keys(v).includes(namespace.at(-1))){
v[0] = 'before'
v["Z"] = 'after'
return v
}
}
}
if(v["Z"]) {
delete v["Z"]
delete v[0]
}
return v
}
const strV = JSON.stringify(dataTree, replacer, 2)
问题在于没有遵循正确的道路。在上面的示例中,它转到 而不是 .styles.elements.heading.typography.fontSize
styles.typography.fontSize
有什么想法吗?
答:
1赞
Andrew Parks
11/16/2022
#1
如果使用替换程序,则会在替换程序返回的已修改对象上递归调用它。
如果替换程序在树中插入新属性,则很难跟踪替换程序的当前调用正在处理的树中的位置。
您可以改为使用对象执行此操作:
const dataTree = {"styles":{"elements":{"heading":{"typography":{"fontFamily":"Volkorn","fontSize":"16px"}}},"typography":{"fontFamily":"Vollkorn","fontSize":"16px","lineHeight":"1.7"}}};
const namespace = 'styles.typography.fontSize'.split('.');
const replaceAtLocation = (tree, [p,...rest], replacer) => rest.length ?
Object.fromEntries(Object.entries(tree).map(([k,v])=>k===p ?
[k,replaceAtLocation(v, rest, replacer)] : [k,v])) : replacer(tree);
const result = replaceAtLocation(dataTree,namespace,tree=>Object.fromEntries(
Object.entries(tree).flatMap(([k,v])=>k===[...namespace].pop()?
[['A','before'],[k,v],['Z','after']]:[[k,v]])));
console.log(JSON.stringify(result, null, 2));
请注意,我已将“0”替换为“A”,因为“0”将始终作为对象中的第一个属性排序,而不是紧挨在所需属性之前。
评论
0赞
Romain Guillaume
11/16/2022
好吧,你的答案完全有效。它仍然非常紧凑,我需要一些时间才能理解这一切。谢谢!
评论
dataTree
strV
styles.elements.heading.typography.fontSize
styles.typography.fontSize