【go】go 实现excel行专列 将集合进行转列

一、场景一

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)
	}
}

最佳实践:

  1. 上面的append我已经测试过,如果tbody这个map中没有这个string的key会自动创建并赋值
  2. 如果tbody这个map中有了这个key,会再次向key对应的数组中增加元素
  3. 所以放心的使用即可
3.3 总结

上面的2段代码中都有个res的集合
为什么我们不用考虑th和tbody的顺序性,因为同一个res,我们不用考虑
如果不需要其他的特殊的处理数据,我们可以将3.1和3.2放在一起处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值