js 数组解析成多维?

前提

做前后端分离,现有如下数组按照updated_at倒序,根据year做第一级,month做第二级,拼装成多维数组,原先是在php后端进行排序处理,但是通过json传递到前端变成无序,现在想通过js,该如何处理?

[
    {
        "id": 15,
        "year": "2018",
        "month": "03",
        "updated_at": "2018-03-01 15:09:59"
    },
    {
        "id": 14,
        "year": "2018",
        "month": "02",
        "updated_at": "2018-02-24 21:39:53"
    },
    {
        "id": 13,
        "year": "2017",
        "month": "12",
        "updated_at": "2017-12-02 16:45:03"
    },
    {
        "id": 5,
        "year": "2017",
        "month": "11",
        "updated_at": "2017-11-10 17:32:11"
    },
    {
        "id": 7,
        "year": "2017",
        "month": "11",
        "updated_at": "2017-11-07 17:26:09"
    },
    {
        "id": 9,
        "year": "2017",
        "month": "10",
        "updated_at": "2017-10-23 19:08:12"
    },
    {
        "id": 8,
        "year": "2017",
        "month": "10",
        "updated_at": "2017-10-20 20:13:07"
    },
    {
        "id": 10,
        "year": "2017",
        "month": "09",
        "updated_at": "2017-09-23 19:05:52"
    },
    {
        "id": 4,
        "year": "2017",
        "month": "09",
        "updated_at": "2017-09-18 17:32:49"
    },
    {
        "id": 3,
        "year": "2017",
        "month": "07",
        "updated_at": "2017-07-22 17:34:20"
    },
    {
        "id": 6,
        "year": "2017",
        "month": "07",
        "updated_at": "2017-07-02 17:28:49"
    },
    {
        "id": 12,
        "year": "2017",
        "month": "06",
        "updated_at": "2017-06-15 15:31:18"
    },
    {
        "id": 11,
        "year": "2017",
        "month": "06",
        "updated_at": "2017-06-11 15:32:16"
    }
]

期望所得数据如下

    "2018": {
        "03": [{
            "id": 15,
            "updated_at": "2018-03-01"
        }],
        "02": [{
            "id": 14,
            "updated_at": "2018-02-24"
        }]
    },
    "2017": {
        "12": [{
            "id": 13,
            "updated_at": "2017-12-02"
        }],
        "11": [{
            "id": 5,
            "updated_at": "2017-11-10"
        }, {
            "id": 7,
            "updated_at": "2017-11-07"
        }],
        "10": [{
            "id": 9,
            "updated_at": "2017-10-23"
        }, {
            "id": 8,
            "updated_at": "2017-10-20"
        }],
        "09": [{
            "id": 10,
            "updated_at": "2017-09-23"
        }, {
            "id": 4,
            "updated_at": "2017-09-18"
        }],
        "07": [{
            "id": 3,
            "updated_at": "2017-07-22"
        }, {
            "id": 6,
            "updated_at": "2017-07-02"
        }],
        "06": [{
            "id": 12,
            "updated_at": "2017-06-15"
        }, {
            "id": 11,
            "updated_at": "2017-06-11"
        }]
    }
}
阅读 2.1k
2 个回答

请补充说明期望的结果(给出例子)

更新

首先,JS 对象中的键是不保证顺序的

也就是说:

let years = {}
years['2018'] = 'haha'
years['2017'] = 'heihei'
console.log(Object.keys(years)) // 不保证是 ['2018', '2017'],有可能是 ['2017', '2018']
console.log(years) // 不保证是 {2018: 'haha', 2017: 'heihei'},有可能是 {2017: 'heihei', 2018: 'haha'}

在此基础之上,如果仍要做的话,可以按照以下步骤:

将原数组按照 year->month 的顺序排序

  • 如果 year month 正是 updated_at 中的年月的话,按照 updated_at 倒序其实就已经按照 year->month 排好了
  • 如果不是的话,手动排一下:
data.sort(function (d1, d2) => {
  if (d1.year > d2.year) return -1
  if (d1.year < d2.year) return 1
  return (+d2.month) - (+d1.month)
})

此时遍历 data 即可

let years = {}
data.forEach(function (d) => {
  if (!years[d.year]) years[d.year] = {}
  let thisYear = years[d.year]
  if (!thisYear[d.month]) thisYear[d.month] = []
  thisYear[d.month].push({
    id: d.id,
    updated_at: d.updated_at
  })
})
consol.log(years) // 就是你要的结果了

整理下代码:

const result = data
  .sort((d1, d2) => {
    if (d1.year > d2.year) return -1
    if (d1.year < d2.year) return 1
    return (+d2.month) - (+d1.month)
  })
  .reduce((years, {id, year, month, updated_at}) => {
    const thisYear = (years[year] = years[year] || {})
    const thisMonth = (thisYear[month] = thisYear[month] || [])
    thisMonth.push({id, updated_at})
    return acc
  }, {})

如果一定要保证键的顺序的话,可以使用 Map它是保证顺序的

const result = data
  .sort((d1, d2) => {
    if (d1.year > d2.year) return -1
    if (d1.year < d2.year) return 1
    return (+d2.month) - (+d1.month)
  })
  .reduce((years, {id, year, month, updated_at}) => {
    if (!years.has(year)) years.set(year, new Map())
    const thisYear = years.get(year)
    if (!thisYear.has(month)) thisYear.set(month, [])
    const thisMonth = thisYear.get(month)
    thisMonth.push({id, updated_at})
    return acc
  }, new Map())

希望对你有帮助

data.sort((a,b)=>b.updated_at.replace(/[-\s:]/g,"")-a.updated_at.replace(/[-\s:]/g,""));
var arr = {};
//data.map((item)=>{
//    arr[item.year]?arr[item.year].push(item):arr[item.year]=[item]
//})
//修改
data.map((item)=>{
    if(!arr[item.year]){
        arr[item.year]={}
    }
    arr[item.year][item.month]?arr[item.year][item.month].push(item):arr[item.year][item.month]=[item]
})
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题