从Golang中的多行json文件创建值列表

huangapple go评论68阅读模式
英文:

Create list of values from a json file of multiple lines in Golang

问题

我需要从JSON输入中创建一个值列表。例如,如果输入是:(这是一个文件。下面的内容是为了这个问题而提到的)

x := `[
	{
		"customer_id": "g62"
	},
	{			
		"customer_id": "b23"
	},
	{			
		"customer_id": "a34"
	},
	{		
		"customer_id": "c42"
	}
	
]`

输出需要以JSON格式显示:

{"Customer_id":["g62","b23","a34","c42"]}

我已经编写了一段代码,得到了以下结果:

[{"Tenant_id":"7645","Customer_id":["g62","b23","a34","c42"]}]

我有一个额外的字段Tenant_id,我认为这段代码不够高效,因为我需要创建一个映射和一个列表来实现这一点。我查找了许多在线示例,但没有找到任何特定的可以帮助我改进的示例。我的目标是使其更高效并且去掉额外的字段"tenant_id"。任何评论或帮助都将不胜感激。

注意:我使用了tenant_id,因为我需要一个键来作为我的映射。我正在寻找替代的解决方案或想法!

以下是工作的代码:

package main

import (
	"encoding/json"
	"fmt"
)

type InpData struct {
	Tenant_id   string
	Customer_id []string
}

type InpList []InpData

func main() {
	x := `[
		{
			"customer_id": "g62"
		},
		{			
			"customer_id": "b23"
		},
		{			
			"customer_id": "a34"
		},
		{		
			"customer_id": "c42"
		}
		
	]`

	var v InpList

	if err := json.Unmarshal([]byte(x), &v); err != nil {
		fmt.Println(err)
	}

	fmt.Printf("%+v", v)

	fmt.Println("\nJson out of list:")
	fmt.Println()

	j, err := json.Marshal(v)
	if err != nil {
		fmt.Printf("Error: %s", err.Error())
	} else {
		fmt.Println(string(j))
	}
}

func (v *InpList) UnmarshalJSON(b []byte) error {
	// Create a local struct that mirrors the data being unmarshalled
	type mciEntry struct {
		Tenant_id   string `json:"tenant_id"`
		Customer_id string `json:"customer_id"`
	}
	var tenant_id string
	tenant_id = "7645"

	type InpSet map[string][]string

	var entries []mciEntry

	// unmarshal the data into the slice
	if err := json.Unmarshal(b, &entries); err != nil {
		return err
	}

	tmp := make(InpSet)

	// loop over the slice and create the map of entries
	for _, ent := range entries {
		tmp[tenant_id] = append(tmp[tenant_id], ent.Customer_id)
	}

	fmt.Println()

	tmpList := make(InpList, 0, len(tmp))

	for key, value := range tmp {
		tmpList = append(tmpList, InpData{Tenant_id: key, Customer_id: value})
	}

	*v = tmpList

	return nil
}

希望这可以帮助到你!

英文:

I need to create a list of values from JSON input. For example, if the input is: (this is a file. The content below is mentioned for this question)

x := `[
{
"customer_id": "g62"
},
{			
"customer_id": "b23"
},
{			
"customer_id": "a34"
},
{		
"customer_id": "c42"
}
]`

The output needs to be in json format:
{"Customer_id":["g62","b23","a34","c42"]}

I have come up with a code which gives out following:
[{"Tenant_id":"7645","Customer_id":["g62","b23","a34","c42"]}]

I have an extra field of Tenant_id and I don't think this code is efficient since I need to create a map and then a list to achieve this. I looked for many online examples but I couldn't find any specific one which can help me do better. My goal here is to make it efficient and git rid of an extra field "tenant_id". Any comment or help is appreciated.

Note: I made use of tenant_id since I needed to have a key for my map.
I am looking for an alternative solution or idea!

The code below is working:

package main
import (
"encoding/json"
"fmt"
)
type InpData struct {
Tenant_id   string
Customer_id []string
}
type InpList []InpData
func main() {
x := `[
{
"customer_id": "g62"
},
{			
"customer_id": "b23"
},
{			
"customer_id": "a34"
},
{		
"customer_id": "c42"
}
]`
var v InpList
if err := json.Unmarshal([]byte(x), &v); err != nil {
fmt.Println(err)
}
fmt.Printf("%+v", v)
fmt.Println("\nJson out of list:")
fmt.Println()
j, err := json.Marshal(v)
if err != nil {
fmt.Printf("Error: %s", err.Error())
} else {
fmt.Println(string(j))
}
}
func (v *InpList) UnmarshalJSON(b []byte) error {
// Create a local struct that mirrors the data being unmarshalled
type mciEntry struct {
Tenant_id   string `json:"tenant_id"`
Customer_id string `json:"customer_id"`
}
var tenant_id string
tenant_id = "7645"
type InpSet map[string][]string
var entries []mciEntry
// unmarshal the data into the slice
if err := json.Unmarshal(b, &entries); err != nil {
return err
}
tmp := make(InpSet)
// loop over the slice and create the map of entries
for _, ent := range entries {
tmp[tenant_id] = append(tmp[tenant_id], ent.Customer_id)
}
fmt.Println()
tmpList := make(InpList, 0, len(tmp))
for key, value := range tmp {
tmpList = append(tmpList, InpData{Tenant_id: key, Customer_id: value})
}
*v = tmpList
return nil
}

答案1

得分: 1

似乎不应该比这个更复杂:

package main

import (
	"encoding/json"
	"fmt"
)

type Input struct {
	CustomerId string `json:"customer_id"`
}
type InputList []Input

type Output struct {
	CustomerIds []string `json:"Customer_id"`
}

func main() {
	jsonSource := `[
        { "customer_id": "g62" },
        { "customer_id": "b23" },
        { "customer_id": "a34" },
        { "customer_id": "c42" }
    ]`

	input := deserialize(jsonSource)
	fmt.Println()
	fmt.Println("Input:")
	fmt.Printf("%+v\n", input)

	output := transform(input)
	fmt.Println()
	fmt.Println("Output:")
	fmt.Printf("%+v\n", output)

	jsonFinal := serialize(output)
	fmt.Println()
	fmt.Println("Final JSON:")
	fmt.Println(jsonFinal)

}

func deserialize(s string) InputList {
	var input InputList
	if err := json.Unmarshal([]byte(s), &input); err != nil {
		panic(err)
	}
	return input
}

func transform(input InputList) Output {
	output := Output{
		CustomerIds: make([]string, 0, len(input)),
	}
	for _, item := range input {
		output.CustomerIds = append(output.CustomerIds, item.CustomerId)
	}
	return output
}

func serialize(output Output) string {
	buf, err := json.Marshal(output)
	if err != nil {
		panic(err)
	}
	s := string(buf)
	return s
}
英文:

Doesn't seem like it should be any more complicated than something like this:

https://goplay.tools/snippet/IhRc4tV9UH0

package main

import (
	"encoding/json"
	"fmt"
)

type Input struct {
	CustomerId string `json:"customer_id"`
}
type InputList []Input

type Output struct {
	CustomerIds []string `json:"Customer_id"`
}

func main() {
	jsonSource := `[
        { "customer_id": "g62" },
        { "customer_id": "b23" },
        { "customer_id": "a34" },
        { "customer_id": "c42" }
    ]`

	input := deserialize(jsonSource)
	fmt.Println()
	fmt.Println("Input:")
	fmt.Printf("%+v\n", input)

	output := transform(input)
	fmt.Println()
	fmt.Println("Output:")
	fmt.Printf("%+v\n", output)

	jsonFinal := serialize(output)
	fmt.Println()
	fmt.Println("Final JSON:")
	fmt.Println(jsonFinal)

}

func deserialize(s string) InputList {
	var input InputList
	if err := json.Unmarshal([]byte(s), &input); err != nil {
		panic(err)
	}
	return input
}

func transform(input InputList) Output {
	output := Output{
		CustomerIds: make([]string, 0, len(input)),
	}
	for _, item := range input {
		output.CustomerIds = append(output.CustomerIds, item.CustomerId)
	}
	return output
}

func serialize(output Output) string {
	buf, err := json.Marshal(output)
	if err != nil {
		panic(err)
	}
	s := string(buf)
	return s
}

huangapple
  • 本文由 发表于 2022年4月13日 05:38:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/71849417.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定