Go语言中将[]slice转换为同键[]map的高效实现方案问询
优化思路说明
你当前实现的时间复杂度已经是该场景下的理论最优值:转换逻辑需要将每一行的每个单元格和表头映射,本质就是**O(行数*列数)**的时间复杂度,不存在可以跳过遍历所有单元格的更优算法。你可以从减少 runtime 额外开销的角度做如下优化:
- 预分配结果切片容量:提前知道
rows的长度就是最终结果切片的长度,初始化时直接指定容量,避免append时动态扩容带来的内存拷贝开销 - 预分配每行map的容量:每个map的键数量固定等于表头长度,初始化map时指定容量,避免map插入元素时的哈希表扩容重排开销
- 减少冗余分支判断:如果能保证所有行的列数和表头长度一致,可以去掉内层循环里
i < length的分支判断;如果不能保证,也可以提前取行长度和表头长度的最小值作为内层循环上限,减少每次循环的判断开销
优化后代码实现
package main import ( "fmt" ) func main() { header := []string{"first", "second", "third"} rows := [][]string{{"1.1", "1.2", "1.3"}, {"2.1", "2.2", "2.3"}, {"3.1", "3.2", "3.3"}} headerLen := len(header) // 预分配结果切片容量 values := make([]map[string]interface{}, 0, len(rows)) for _, row := range rows { // 预分配map容量 dict := make(map[string]interface{}, headerLen) rowLen := len(row) // 取最小长度作为循环上限,避免循环内每次判断 loopCnt := min(headerLen, rowLen) for i := 0; i < loopCnt; i++ { dict[header[i]] = row[i] } values = append(values, dict) } fmt.Println(values) } // Go 1.21及以上版本可直接使用内置min函数,无需自行实现 func min(a, b int) int { if a < b { return a } return b }
泛型通用实现(Go 1.18+版本可用)
如果需要适配不同类型的行值,可以用泛型封装通用转换函数:
func RowsToMaps[T any](header []string, rows [][]T) []map[string]interface{} { headerLen := len(header) res := make([]map[string]interface{}, 0, len(rows)) for _, row := range rows { dict := make(map[string]interface{}, headerLen) loopCnt := min(headerLen, len(row)) for i := 0; i < loopCnt; i++ { dict[header[i]] = row[i] } res = append(res, dict) } return res }
内容的提问来源于stack exchange,提问作者williamfinn
相关产品推荐
相关产品推荐

