js遍历数组嵌套实现数据格式转换?

原本数据格式:

    let list2 = [
        {
            name: "教学机构",
            value: [
               {
                   name: "专业资源库",
                   value: [{name: "2019-2020", value: 0}, {name: "2020-2021", value: 0}, {name: "2021-2022", value: 0}]
               },
               {
                   name: "专业教学资源库",
                   value: [{name: "2019-2020", value: 0}, {name: "2020-2021", value: 0}, {name: "2021-2022", value: 0}]
               }
           ]
        },
        {
            name: "教学机构2",
            value: [
                {
                    name: "专业资源库",
                    value: [{name: "2019-2020", value: 0}, {name: "2020-2021", value: 0}, {name: "2021-2022", value: 0}]
                },
                {
                    name: "专业教学资源库",
                    value: [{name: "2019-2020", value: 0}, {name: "2020-2021", value: 0}, {name: "2021-2022", value: 0}]
                }
            ]
        },
        {
            name: "教学机构3",
            value: [
                {
                    name: "专业资源库",
                    value: [{name: "2019-2020", value: 0}, {name: "2020-2021", value: 0}, {name: "2021-2022", value: 0}]
                },
                {
                    name: "专业教学资源库",
                    value: [{name: "2019-2020", value: 0}, {name: "2020-2021", value: 0}, {name: "2021-2022", value: 0}]
                }
            ]
        }
    ]

目标格式转换如下:

  1. 实现目标格式一:

    let targetArr1 = [
       {
           name: "专业资源库",
           value: [
               {
                   name: "教学机构1",
                   value: [{name: "2019-2020", value: 0}, {name: "2020-2021", value: 0}, {name: "2021-2022", value: 0}]
               },
               {
                   name: "教学机构2",
                   value: [{name: "2019-2020", value: 0}, {name: "2020-2021", value: 1}, {name: "2021-2022", value: 0}]
               },
               {
                   name: "教学机构3",
                   value: [{name: "2019-2020", value: 0}, {name: "2020-2021", value: 2}, {name: "2021-2022", value: 3}]
               }
           ]
       },
       {
           name: "专业教学资源库",
           value: [
               {
                   name: "教学机构1",
                   value: [{name: "2019-2020", value: 0}, {name: "2020-2021", value: 0}, {name: "2021-2022", value: 0}]
               },
               {
                   name: "教学机构2",
                   value: [{name: "2019-2020", value: 0}, {name: "2020-2021", value: 1}, {name: "2021-2022", value: 0}]
               },
               {
                   name: "教学机构3",
                   value: [{name: "2019-2020", value: 0}, {name: "2020-2021", value: 1}, {name: "2021-2022", value: 10}]
               }
           ]
       },
      ]
    
  2. 实现目标格式二:
    统计属性值name为年份的value总和

     let targetArr2 = [
       {
           name: "专业资源库",
           value: [
               {name: "2019-2020", value: 0},
               {name: "2020-2021", value: 1},
               {name: "2021-2022", value: 5}
           ]
       },
       {
           name: "专业教学资源库",
           value: [
               {name: "2019-2020", value: 0},
               {name: "2020-2021", value: 2},
               {name: "2021-2022", value: 10}
           ]
       },
      ]
阅读 1.6k
2 个回答

分组和 Sum 懒得自己写,用的 Lodash,所以就用 Lodash 来处理了。


// 先展开成平面的(列表)
const flatTable = list2.flatMap(
    org => org.value.flatMap(
        lib => lib.value.map(
            year => ({
                org: org.name,
                lib: lib.name,
                year: year.name,
                value: year.value
            })
        )
    )
);

// 再按要求进行分组
// 先按 lib 分,再按 org 分
const r1 = _(flatTable)
    .groupBy(it => it.lib)
    .mapValues(orgs => _(orgs)
        .groupBy(it => it.org)
        .map((years, name) => ({
            name,
            value: years.map((it, value) => ({ name: it.year, value }))
        }))
        .value()
    )
    .value();

// 先按 lib 分
// 再按 year 分
// 并对 year 分组之后的数据进行汇总
const r2 = _(flatTable)
    .groupBy(it => it.lib)
    .mapValues(orgs => _(orgs)
        .groupBy(it => it.year)
        .map((its, name) => ({
            name,
            value: _.sumBy(its, it => it.value)
        }))
        .value()
    )
    .value();

写了篇博文:在前端使用 JS 进行分类汇总

先分组,再合并

function arrayTransform(arr){
    if(!Array.isArray(arr)){
        return []
    }
    let group = arr.reduce((p,v)=>{
        p[0].push(v.value.reduce((i,j)=>{
            i.name = v.name;
            i.value = j.value
            if(p[1].every(t=>t.name != j.name)){
                p[1].push({
                    name:j.name,
                    value:[]
                })
            }
            return v
        },{}))
        return p
    },[[],[]])

    return group[1].reduce((p,i)=>{
        i.value = group[0]
        p.push(i)
        return p
    },[])
}
推荐问题
宣传栏