对后端返回的数据进行重组之柱状图

83 阅读2分钟

最近要做类似如下的柱状图:

image.png 针对以上柱状图,后台给我返回了这样一组数据:

// 模拟从后台传回来的数据
let res = [
    { weekFlag: '本周', period: 'Mon', count: 58 },
    { weekFlag: '下周', period: 'Mon', count: 58 },
    { weekFlag: '下周', period: 'Wed', count: 60 },
    { weekFlag: '本周', period: 'Wed', count: 69 },
    { weekFlag: '本周', period: 'Thu', count: 81 },
    { weekFlag: '本周', period: 'Fri', count: 100 },
    { weekFlag: '下周', period: 'Tus', count: 26 },
    { weekFlag: '本周', period: 'Tus', count: 26 },
    { weekFlag: '下周', period: 'Thu', count: 85 },
    { weekFlag: '下周', period: 'Fri', count: 100 }
]

实际上我需要的数据是这样的:

let bar = [
  { '日期': '本周', '周一': 58, '周二': 26, '周三': 69, '周四': 81, '周五': 100 },
  { '日期': '下周', '周一': 58, '周二': 26, '周三': 60, '周四': 85, '周五': 100 } 
]

首先采用最笨的方法如下:

// 第一步:按照 weekFlag 分成 ‘本周’ 和 ‘下周’ 两个数组
let currWeek = []
let nextWeek = []
res.forEach(item=>{
    if(item.weekFlag == '本周'){
        currWeek.push(item)
    }else if(item.weekFlag == '下周') {
        nextWeek.push(item)
    }
})

// 第二步:对以上数组分别循环,给对象动态添加属性,顺手改为中文键名
let currData = {}
currWeek.forEach(item=>{
    currData['日期'] = '本周'
    if(item.period === 'Mon'){
        currData['周一'] = item.count
    }else if(item.period == 'Tus'){
        currData['周二'] = item.count
    }else if(item.period == 'Wed'){
        currData['周三'] = item.count
    }else if(item.period == 'Thu'){
        currData['周四'] = item.count
    }else if(item.period == 'Fri'){
        currData['周五'] = item.count
    }
})
let nextData = {}
nextWeek.forEach(item=>{
    nextData['日期'] = '下周'
    if(item.period == 'Mon'){
        nextData['周一'] = item.count
    }else if(item.period == 'Tus'){
        nextData['周二'] = item.count
    }else if(item.period == 'Wed'){
        nextData['周三'] = item.count
    }else if(item.period == 'Thu'){
        nextData['周四'] = item.count
    }else if(item.period == 'Fri'){
        nextData['周五'] = item.count
    }
})
// 合并两个对象,完成
let barData = [currData,nextData]
console.log(barData)

当然,以上方法简单粗暴易理解!但是不能复用,且冗余!如果你的数据足够庞大,if-else 的嵌套会很深,我们不妨试试另一种方法!如果你足够勤快,还可以封装成函数,进行复用。

// 第一步:同第一种方法,拆分成两个数组,只不过这里用的 filter 更高级
let currData = res.filter(item=>item.weekFlag==='本周')
let nextData = res.filter(item=>item.weekFlag==='下周')

// 第二步:分别循环上面的两个数组,给对象动态添加属性
let currObj = {}
currData.forEach(item=>{
    currObj[item.period] = item.count
    currObj['weekFlag'] = '本周'
})
let nextObj = {}
nextData.forEach(item=>{
    nextObj[item.period] = item.count
    nextObj['weekFlag'] = '下周'
})
// 第三步:合并俩对象
let barData = [currObj,nextObj]

// 第四步:英文键名改中文键名
let objMap = {
    weekFlag: '日期',
    Mon: '周一',
    Tus: '周二',
    Wed: '周三',
    Thu: '周四',
    Fri: '周五'
}
let rowData = []
barData.forEach(item=> {
    let obj ={}
    Object.keys(item).forEach(key=> {
        // 获取中文键名
        let innerKey = objMap[key]
        if(innerKey){
            obj[innerKey] = item[key]
        }else {
            obj[key] = item[key]
        }
    })
    rowData.push(obj)
})
console.log(rowData)