如何把一个有很多级关系的json对象,转化成一个一层的数组展示?

如题,我们有一个图书目录的数据,如图所示,结构是这样的:

clipboard.png

有些章节只有一级目录,有些可能多级目录。
结构是如下形式

{{href:xxx,label:'第一章',subitems[{href:xxx,label:xxx,subitems:xxx},{href:xxx,label:xxx,subitems:xxx}]}}

需要转成如下的格式:

转化后=

[
{href:xxxx,chapter:['扉页']},
{href:yyyy,chapter:['第一章','第一节']},
]

就是说,把一个立体的结构给改成一个平面的,方便后面的代码使用。

请问这个该怎么做啊?头疼啊!

多谢各位

阅读 4.8k
3 个回答

你把json内容copy出来,我看看。
我理了一下,你这个json不对:

// a 不是一个标准的json
var a = [{
    {
        href:xxx,
        label:'第一章',
        subitems: [
        {
            href:xxx,
            label:xxx,
            subitems:xxx
        },{
            href:xxx,
            label:xxx,
            subitems:xxx
        }
        ]
    }
}]
        
        
var b = [{
    href:xxxx,
    chapter:['扉页']
},{
    href:yyyy,
    chapter:['第一章','第一节']
}]
        
        
// 大概方法这样
var c = [];
// 循环读取subitems
function readJson (json, arr) {
    if (!json.subitems) {
        arr.push(json.label)
        return arr;
    } else {
        return readJson (json.subitems, arr)
    }
}
for (let i=0, len=json.length; i<len; i++) {
        var obj = {
            href: '',
            chapter: []
        };
        obj.href = json[i].href;
        for (let j=0, lenj=json[i].subitems.length; j<lenj; j++) {
            readJson (json[i].subitems[j].subitems, obj.chapter)
        }
        c.push(obj);
    }
console.log(c);    

使用递归
文字思路:循环数组,再循环数组中的对象的属性,如果这个属性是个数组,再调用本方法,否则把这个属性push到新数组中去,就OK了

先给好你的 mock data 吧,我也只能猜。。。

var data = [
    {
        href: 'text/part0001.html',
        label: '扉页'
    },
    {
        href: 'text/part0002.html',
        label: '前言'
    },
    {
        href: 'text/part0003.html',
        label: '目录',
        subitems: [
            {
                href: 'text/part1001.html',
                label: '目录第一页'
            },
            {
                href: 'text/part1002.html',
                label: '目录第二页'
            },
            {
                href: 'text/part1003.html',
                label: '目录第三页'
            }
        ]
    },
    {
        href: 'text/part0004.html',
        label: '第一章',
        subitems: [
            {
                href: 'text/part0005.html',
                label: '没有人能打败趋势',
                subitems: [
                    {
                        href: 'text/part0006.html',
                        label: '测试'
                    }
                ]
            }
        ]
    }
]

function flattenJson(data) {
    return data.map(e => {
        let obj = {};
        obj.href = e.href;
        obj.chapter = [e.label];
        if (e.hasOwnProperty('subitems')) {
            let childArr = flattenJson(e.subitems).map(e => e.chapter);
            obj.chapter = obj.chapter.concat([].concat.apply([], childArr));
        }
        return obj;
    });
}

最后得到:

clipboard.png

不过这样做的话,所有子级的 href 都不会保留下来。如果你也要留下所有子级的 href,在 if 里面改一下应该就行了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题