将两个列表转换为json

时间:2019-07-10 14:21:05

标签: javascript json

我正在尝试将两个列表转换为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"
            }]
        }
    ]
}]

5 个答案:

答案 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 }] )