我正在尝试将两个列表转换为json。
例如:
l1 = ['a','b','a']
l2 = ['q','r','s']
应转换为:
[{
"name": "g",
"children": [{
"name": "a",
"children": [{
"name": "q"
}, {
"name": "s"
}]
},
{
"name": "b",
"children": [{
"name": "r"
}]
}
]
}]
我最近的是:
l1 = ['a','b','a']
l2 = ['q','r','s']
nameDict = {}
childrenDict = {}
l1 = l1.map(x => {
return({name: x});
});
console.log(l1);
l2 = l2.map(x => {
return({children: x});
});
console.log(l2);
var c = l1.map(function(e, i) {
return [e, l2[i]];
});
console.log(JSON.stringify(c))
产生:
[[{"name":"a"},{"children":"q"}],
[{"name":"b"},{"children":"r"}],
[{"name":"a"},{"children":"s"}]]
如何结合产生的要素? :
[{
"name": "g",
"children": [{
"name": "a",
"children": [{
"name": "q"
}, {
"name": "s"
}]
},
{
"name": "b",
"children": [{
"name": "r"
}]
}
]
}]
答案 0 :(得分:1)
免责声明:由于我们不知道g
的来源,因此我只会构建根children
数组。
由于数组的长度相同,因此可以使用普通的for
并与索引一起使用以同时处理两个数组。只需构建一个数组并检查每个迭代是否已经存在“子”即可。如果没有,请创建它。
l1 = ['a','b','a']
l2 = ['q','r','s']
let gChildren = []
for(let i = 0; i < l1.length; i++){
let group = gChildren.find(c => c.name === l1[i])
if(!group){
group = { name: l1[i], children: [] }
gChildren.push(group)
}
group.children.push({ name: l2[i] })
}
console.log(gChildren)
答案 1 :(得分:1)
这里的工作代码说明了您已经存在的结构,可以完成您想要的结果。
let data1 = ["a","b","a"];
let data2 = ["q","r","s"];
let outputData = [{name: "g", children: []}];
for (let i=0;i < data1.length;i++) {
let found = false;
for (let j=0;j < outputData[0].children.length;j++) {
if (outputData[0].children[j].name === data1[i]) {
outputData[0].children[j].children.push({name: data2[i]});
found = true;
}
}
if (found === false) {
outputData[0].children.push({name: data1[i], children: [{name: data2[i]}]});
}
}
console.log(JSON.stringify(outputData));
答案 2 :(得分:0)
这是Array.prototype.reduce的一个很好的用例,在这里您要遍历数组,但最后得到一个值。
l1.reduce((acc, val, i) => {
const l2Val = l2[i]
const foundObj = acc.find(o => o.name === val)
if (foundObj) {
foundObj.children.push({name: l2Val})
} else {
acc.push({
name: val,
children: [{name: l2Val}]
})
}
return acc
}, [])
在这里,在每次迭代中,我只是将子项添加到该项的children数组中,或者为该项创建值(如果尚不存在)。
我不知道g
对应什么,因此省略了它,但是如果需要,您可以将从reduce
创建的数组添加到另一个对象或数组。
答案 3 :(得分:0)
您可以转置数组并将信息用作最终子对象的路径
l1 = ['a', 'b', 'a']
l2 = ['q', 'r', 's']
转置为
[
['a', 'q'], // a -> q
['b', 'r'], // b -> r
['a', 's'] // a -> s
]
现在可以与reduce一起使用。
优点是可以使用更长的路径访问最终的孩子,例如
[
['a', 'x', 'y', 'z'],
...
]
返回彼此具有给定关系的嵌套对象。
const
transpose = array => array.reduce((r, a) => a.map((v, i) => [...(r[i] || []), v]), []);
var l1 = ['a', 'b', 'a'],
l2 = ['q', 'r', 's'],
result = transpose([l1, l2]).reduce((r, a) => {
a.reduce((q, name) => {
var temp = (q.children = q.children || []).find(o => o.name === name);
if (!temp) q.children.push(temp = { name });
return temp
}, r);
return r;
}, { name: 'g' });
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 4 :(得分:0)
在各个按键上使用过滤器时要短一些:
var l1 = ['a','b','a'], l2 = ['q','r','s']
var children = [...new Set(l1)].map(k => ({ name: k, children:
l2.filter((v, i) => l1[i] == k).map(v => ({ name: v })) }))
console.log( [{ name: 'g', children }] )
或更有效的使用组的中间对象:
var l1 = ['a','b','a'], l2 = ['q','r','s']
var children = Object.entries(
l1.reduce((o, k, i) => ((o[k] = o[k] || []).push(l2[i]), o), {})
).map(([k, v]) => ({ name: k, children: v.map(v => ({ name: v})) }))
console.log( [{ name: 'g', children }] )