Golang动态创建JSON键的方法与技巧

Golang动态创建JSON键的方法与技巧 你好!

我是Go语言的初学者,也是这个论坛社区的新成员。

我有一些文本文件,每行都具有相同的结构 text = value,我想将每个文件转换为JSON文件。

示例:

文件1:

city =  Berlin,  inhabitant = 10 
city =  London,  inhabitant = 20 

文件2:

color =  blue,  size = 10
color =  red,  size = 20

文件3(包含我想保留的重复条目):

color =  blue,  size = 10, size = 10
color =  red,  size = 20, size = 20

期望的JSON格式:

file1: [
        {
           "city" :  "Berlin",  "inhabitant" : 10 
        }, 
        {
           "city" :  "London",  "inhabitant" : 20 
        }
]

file2: [
     {
        "color" :  "blue", 
        "size" : 10 
     }, 
     {
        "color" :  "red",  
        "size" :  20 
     }
]

file3: [
      {
          "color" : "blue",  
          "size" : 10, 
          "size" : 10 
       }, 
       {
           "color" : "red",  
            "size" : 20, 
            "size" : 20 
       }
]

如何为每个文件动态转换键(city、color、size)? 使用interface{}是实现这个的方法吗?

谢谢!


更多关于Golang动态创建JSON键的方法与技巧的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

感谢您的回答。

我已经决定不再关心重复的问题。 我使用一个 map[int]map[string]string,将其转换为 JSON,通过 json.MarshalIndent() 方法得到了我期望的结果。

func main() {
    fmt.Println("hello world")
}

更多关于Golang动态创建JSON键的方法与技巧的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


引用 pchp:

{ “color” : “red”, “size” : 20, “size” : 20 }


这不是有效的 JSON。相同的属性不能出现多次。你可以考虑将其改为数组形式:

```json
{ "color" : "red", "size" : [20, 20] }

在Go语言中,动态创建JSON键可以通过使用map[string]interface{}来实现。这种方法允许你在运行时动态地设置键值对,而不需要预定义结构体。以下是一个完整的示例代码,展示如何解析你的文本文件并生成所需的JSON格式。

首先,读取文件内容,解析每一行,提取键值对,然后构建一个map[string]interface{}的切片。最后,使用json.Marshal将数据转换为JSON。

package main

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

func parseLine(line string) map[string]interface{} {
    // 移除行中的空格并分割键值对
    parts := strings.Split(line, ",")
    result := make(map[string]interface{})
    
    for _, part := range parts {
        // 分割每个键值对
        kv := strings.Split(strings.TrimSpace(part), "=")
        if len(kv) != 2 {
            continue // 跳过无效格式
        }
        key := strings.TrimSpace(kv[0])
        value := strings.TrimSpace(kv[1])
        
        // 尝试将值转换为整数,如果失败则保留为字符串
        if intValue, err := parseInt(value); err == nil {
            result[key] = intValue
        } else {
            result[key] = value
        }
    }
    return result
}

func parseInt(s string) (int, error) {
    var val int
    _, err := fmt.Sscanf(s, "%d", &val)
    return val, err
}

func main() {
    // 示例文件内容(模拟文件读取)
    file1Lines := []string{
        "city =  Berlin,  inhabitant = 10",
        "city =  London,  inhabitant = 20",
    }
    
    file2Lines := []string{
        "color =  blue,  size = 10",
        "color =  red,  size = 20",
    }
    
    file3Lines := []string{
        "color =  blue,  size = 10, size = 10",
        "color =  red,  size = 20, size = 20",
    }
    
    // 处理每个文件
    processFile(file1Lines, "file1")
    processFile(file2Lines, "file2")
    processFile(file3Lines, "file3")
}

func processFile(lines []string, filename string) {
    var data []map[string]interface{}
    for _, line := range lines {
        parsed := parseLine(line)
        data = append(data, parsed)
    }
    
    jsonData, err := json.MarshalIndent(data, "", "  ")
    if err != nil {
        fmt.Printf("Error marshaling JSON for %s: %v\n", filename, err)
        return
    }
    
    fmt.Printf("%s: %s\n\n", filename, string(jsonData))
}

代码说明:

  • parseLine 函数解析每一行文本,提取键值对。它使用 strings.Splitstrings.TrimSpace 来清理输入。
  • 值被尝试解析为整数(使用 parseInt 函数),如果失败则保留为字符串。这处理了像 inhabitant 这样的数字字段。
  • processFile 函数处理文件的所有行,构建一个 map[string]interface{} 切片,并使用 json.MarshalIndent 生成格式化的JSON输出。

输出示例(针对file3):

file3: [
  {
    "color": "blue",
    "size": 10,
    "size": 10
  },
  {
    "color": "red",
    "size": 20,
    "size": 20
  }
]

注意:在JSON中,键必须是唯一的。如果你的输入包含重复键(如file3中的多个size),在Go的map中,后面的值会覆盖前面的。如果你需要保留所有重复键,JSON标准不允许这样做;你可能需要调整数据结构,例如使用切片来存储值(例如 "size": [10, 10])。如果需要这种处理,可以修改解析逻辑来检测重复键并转换为数组。

回到顶部