一、场景一
1、固定列头的行转列
固定列头的行转列:解释一下,转换后的列头(即:昨日日期、今日日期)为固定的,不需要我们处理
需求:用户A下有3个账户(account)然后每个账户在每天都一定的费用产生,然后我们抽取数据需要展示 如下图:
这里我们将A用户的不同account进行了今日和昨日的花费一个对比
在这个场景下,我们需要将数据进行一个行转列的一个操作
2、行转列方式(map数组)
前提我们输出的数据类型为:res := []map[string]interface{}{}
即:map数组
行转列需要一个唯一的参考列,如上图中以 account
为参考列
入参依次为:输出的数组、map的key
返货结果依次为:key是否存在、存在的map、存在的map的索引
// MapKeyExist 根据传入的map列表中,判断是否有个某个map中含有该key
func MapKeyExist(list []map[string]interface{}, key string) (bool, map[string]interface{}, int) {
//fmt.Println(len(list))
if len(list) > 0 {
for i, m := range list {
//fmt.Println(m)
if _, ok := m[key]; ok {
return true, m, i
}
}
}
return false, nil, 0
}
3、如何使用
下面是一段伪代码,简单介绍行转列的思路
请仔细阅读每一行注释,如果有问题,可以在评论区留言
res := []map[string]interface{}{}
if len(从数据库中取出的list) > 0 {
for _, item := range 从数据库中取出的list {
// 判断唯一值在数组中是否存在(这里使用account)
flag, data, index := maputil.MapKeyExist(res, item.Account)
// 如果存在
if flag == true {
// 从数组中获取当前存在的对象
resTemp := res[index]
// 在下面补充上需要的字段
....
} else {
// 初始化一个 map
temp := make(map[string]interface{})
// 这里设置一个唯一列,作为后面合并的参考
temp[item.Account] = item.Account
// 把需要的列可以在插入时补全
temp["xxx"] = 0 // int 给默认值
temp["kkk"] = ""// string 给默认值
// 加到 map数组上
res = append(res, temp)
}
}
}
二、场景二
1、自定义列头的行转列
自定义列头的行转列:解释一下,就是我们将如下图左边的账号
通过行转化为下图右边的列头
需求:用户103下有2个账号,然后每个账号在每天都一定的费用产生,然后我们抽取数据根据服务展示每个账号具体的花费 如下图:
2、行转列方式
和上面场景一的思考方式不同
如果我们要展示如下的数据结构(即:不展示上面的用户一列)
3、如何使用
分析这个table
我们需要将表头Th上面需要动态获取数据
然后table的Tbody中
3.1 组装 th 思路
首先要明确渲染的th就是一个数组,这里我们就使用数组的数据结构
定义 th := []string{}
一段伪代码如下:
th := []string{}
if len(res) > 0 {
for _, temp1 := range res {
index := arrayUtil.In(temp1.Account, th)
if index == false {
th = append(th, temp1.Account)
}
}
}
}
3.2 获取 Tbody 思路
明确了表头,我们将面对每一行都是一个业务名称(列名:service对应的数据),且每个业务的数据要对应着account(动态th表头),最终我们选用map中 string-数组数据结构
如:
{
“service1”:[1,2,3,4,5]
}
定义 tbody := map[string][]interface{}{}
if len(res) > 0 {
for _, temp := range res {
tbody[temp.Service] = append(tbody[temp.Service], totalNum)
}
}
最佳实践:
- 上面的append我已经测试过,如果tbody这个map中没有这个string的key会自动创建并赋值
- 如果tbody这个map中有了这个key,会再次向key对应的数组中增加元素
- 所以放心的使用即可
3.3 总结
上面的2段代码中都有个res的集合
为什么我们不用考虑th和tbody的顺序性,因为同一个res,我们不用考虑
如果不需要其他的特殊的处理数据,我们可以将3.1和3.2放在一起处理