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


    一、场景一

    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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    二、场景二

    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)
    			}
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    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
    • 2
    • 3
    • 4
    • 5

    最佳实践:

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

    3.3 总结

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

  • 相关阅读:
    计算机二级WPS 选择题(模拟和解析十一)
    洛谷 P5682 [CSP-J2019 江西] 次大值
    Redis数据库安装、使用、数据类型、常用命令(详解)
    unity3d 布娃娃系统插件 PuppetMaster 木偶师
    Percolation: Slipping through the Cracks
    【024】C++对C的扩展之命名空间namespace详解
    CMake0721
    强化学习和推荐系统的结合应用
    判断字符串是否唯一
    单元测试界的高富帅,Pytest框架,手把手教学,从入门到精通
  • 原文地址:https://blog.csdn.net/wanglei19891210/article/details/125066073