You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Go语言中将文件路径转换为JSON树形结构

解决Go语言中文件路径转嵌套JSON树形结构的问题

需求描述

需要将以下格式的文件路径列表转换为嵌套的JSON树形结构:

输入示例:

/home/aneesh/Code/GmailProject/main.py, 55
/home/aneesh/Code/Parser/parse.py, 66
/home/user/Project/image.png, 77
/home/user/Music/output.wav, 88

期望输出:

{
    "home": {
        "aneesh": {
            "Code": {
                "GmailProject": {
                    "main.py": 55
                },
                "Parser": {
                    "parse.py": 66
                }
            }
        },
        "user": {
            "Project": {
                "image.png": 77
            },
            "Music": {
                "output.wav": 88
            }
        }
    }
}

问题难点

Go语言的类型系统不像Python那样灵活,无法直接使用多层嵌套的动态映射,map[string]int只能处理叶子节点,无法表示中间的目录节点(目录节点是map[string]interface{}类型),导致构建树形结构时遇到类型转换和嵌套修改的问题。

用户尝试的代码存在的核心问题:

package main

import "fmt"

func main() {
    l := "/home/aneesh/Code/Python/main.py"
    m := make(map[string]bool, 10)
}

func arrange(m *map[string]any, s string) {
    arr := strings.Split(s, "/")[1:]

    ma := *m
    for i, e := range arr {
        if i == len(arr)-1 {
            ma[e] = true
        } else {
            ma = ma[e] // 类型不匹配:ma[e]是bool类型,无法赋值给ma(map[string]any)
        }
    }
}

解决思路

使用map[string]interface{}作为树形结构的通用节点类型,因为每个节点既可以是子目录(map[string]interface{}),也可以是文件对应的数值(int)。通过迭代路径分段逐步构建结构:

  1. 解析每一行输入,拆分出文件路径和对应的数值
  2. 从根节点开始,遍历路径的每一段
  3. 非最后一段(目录):检查当前节点是否存在该目录,不存在则创建新的map[string]interface{}节点,存在则切换到该子节点
  4. 最后一段(文件):将当前节点的对应键赋值为解析出的数值

完整实现代码

package main

import (
	"encoding/json"
	"fmt"
	"strconv"
	"strings"
)

func main() {
	// 模拟输入数据
	inputLines := []string{
		"/home/aneesh/Code/GmailProject/main.py, 55",
		"/home/aneesh/Code/Parser/parse.py, 66",
		"/home/user/Project/image.png, 77",
		"/home/user/Music/output.wav, 88",
	}

	// 根节点,用map[string]interface{}存储树形结构
	root := make(map[string]interface{})

	for _, line := range inputLines {
		// 拆分路径和数值部分
		parts := strings.SplitN(line, ",", 2)
		if len(parts) != 2 {
			continue
		}
		path := strings.TrimSpace(parts[0])
		valueStr := strings.TrimSpace(parts[1])
		value, err := strconv.Atoi(valueStr)
		if err != nil {
			fmt.Printf("无效数值:%s\n", valueStr)
			continue
		}

		// 拆分路径为分段,去掉开头空字符串(因路径以/开头)
		segments := strings.Split(path, "/")[1:]
		if len(segments) == 0 {
			continue
		}

		// 从根节点开始遍历路径分段
		current := root
		for i, seg := range segments {
			if i == len(segments)-1 {
				// 最后一段是文件,赋值对应数值
				current[seg] = value
			} else {
				// 非最后一段是目录,检查是否存在
				node, exists := current[seg]
				if !exists {
					// 不存在则创建新的目录节点
					newNode := make(map[string]interface{})
					current[seg] = newNode
					current = newNode
				} else {
					// 存在则转换为map类型,继续深入
					childMap, ok := node.(map[string]interface{})
					if !ok {
						fmt.Printf("路径冲突:%s 不是目录\n", seg)
						break
					}
					current = childMap
				}
			}
		}
	}

	// 生成格式化的JSON输出
	jsonData, err := json.MarshalIndent(root, "", "    ")
	if err != nil {
		fmt.Println("JSON序列化错误:", err)
		return
	}
	fmt.Println(string(jsonData))
}

代码说明

  1. 输入解析:拆分每行的路径与数值,将字符串数值转为整数
  2. 路径分段处理:拆分路径并过滤开头空字符串,避免无效节点
  3. 树形构建:动态创建目录节点,处理路径冲突(如目录与文件重名)
  4. JSON输出:使用json.MarshalIndent生成可读性强的格式化JSON字符串

内容的提问来源于stack exchange,提问作者Aneesh Bhave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 15:00:59