2014-12-03 169 views
1

我开始出具有平坦JSON输入本身(简单的例子):Javascript:解析和排序扁平json结构为嵌套数组?

[ 
{id:1, value:'child1', parentId:2, sortOrder:1}, 
{id:2, value:'root1', parentId:null, sortOrder:1}, 
{id:3, value:'root2', parentId:null, sortOrder:2}, 
{id:4, value:'child2', parentId:1, sortOrder:2}, 
{id:5, value:'root3', parentId:null, sortOrder:3}, 
{id:6, value:'child1', parentId:2, sortOrder:1}, 
{id:7, value:'root4', parentId:null, sortOrder:4} 
]; 

输入可以是任意深度和长度的,并且需要重新格式化为基于父嵌套阵列的集合 - 儿童关系,以及在每个嵌套级别按升序排序。

原生JS或UnderscoreJS可用于格式化输出。

输出将被格式化为具有基本形式的JSON结构:

root1 
    child1 
    child2 
root2 
    child1 
    child1 
    child2 
    child2 

    etc... 

,其中每个元素是一个JSON对象。

嵌套深度可以是任何东西,因为数据很可能来自具有上述扁平结构的数据库表。

有什么想法?

+0

看看jquery.map – 2014-12-03 20:15:48

+0

[这个答案](http://stackoverflow.com/a/17849353)给了我正是我需要做到这一点。 – melicent 2015-06-04 22:24:11

+0

请了解JSON是什么以及它不是什么。 *有什么想法?*是的,我的想法是,你需要编写一个“计算机程序”来做到这一点。 – 2016-08-17 05:22:41

回答

1

我会做如下工作。我本来可以使用value属性来附加嵌套的对象,但问题不明确。相反,我创建了children属性来构造嵌套结构。

var flat = [ 
 
{id:1, value:'child1', parentId:2, sortOrder:1}, 
 
{id:2, value:'root1', parentId:null, sortOrder:1}, 
 
{id:3, value:'root2', parentId:null, sortOrder:2}, 
 
{id:4, value:'child2', parentId:1, sortOrder:2}, 
 
{id:5, value:'root3', parentId:null, sortOrder:3}, 
 
{id:6, value:'child1', parentId:2, sortOrder:1}, 
 
{id:7, value:'root4', parentId:null, sortOrder:4} 
 
], 
 
    lut = flat.sort((a,b) => a.sortOrder - b.sortOrder) 
 
       .reduce((t,o) => { o.children === void 0 && (o.children = []); 
 
            t[o.id] = t[o.id] === void 0 ? o : (o.children = t[o.id].children,o); 
 
            o.parentId  !== null && 
 
            (t[o.parentId] !== void 0 ? t[o.parentId].children.push(o) 
 
                  : t[o.parentId] = {id: o.parentId, children: [o]}); 
 
            return t; 
 
           },{}), 
 
    nested = Object.keys(lut).reduce((a,k) => lut[k].parentId === null ? a.concat(lut[k]): a,[]); 
 
console.log(nested);

另外,sort阶段不会是必要的,如果你想向孩子们在收到他们的父母的children数组属性对象的方式。

+0

我当然希望我永远不要终止维护代码。 – 2016-08-17 05:24:31

1

我们的计划是将父母下的孩子移到一个新的数组值children属性中,然后将其过滤掉。

const flat = [ 
 
{id:1, value:'child1', parentId:2, sortOrder:1}, 
 
{id:2, value:'root1', parentId:null, sortOrder:1}, 
 
{id:3, value:'root2', parentId:null, sortOrder:2}, 
 
{id:4, value:'child2', parentId:1, sortOrder:2}, 
 
{id:5, value:'root3', parentId:null, sortOrder:3}, 
 
{id:6, value:'child1', parentId:2, sortOrder:1}, 
 
{id:7, value:'root4', parentId:null, sortOrder:4} 
 
]; 
 

 
const nested = flat.filter((elt, idx, arr) => { 
 
    const parent = arr.find(e => e.id === elt.parentId); 
 
    if (!parent) return true; 
 
    (parent.children = parent.children || []).push(elt); 
 
}); 
 

 
console.log(nested);

排序将被留作练习。