Golang中如何生成一对多关系的映射

Golang中如何生成一对多关系的映射 我对Go语言还比较陌生,正在努力从现有的映射生成一个一对多关系的映射。

这是我的脚本 - playground

解释:我试图实现第0个位置的每个元素与第1、2、…、第n个位置的每个元素之间的关系。

例如 - [0][0]=>[1][0], [0][0]=>[1][1], [0][1]=>[1][0], [0][1]=>[1][1], [0][0]=>[2][0], [0][1]=>[2][1]

但是,我无法实现它。 我试图实现的最终输出 -

Array(
[0] => Array
    (
        [0] => Array
            (
                [room_rate_key] => 0|0
                [amount] => 5307.84
            )
        [1] => Array
            (
                [room_rate_key] => 0|0
                [amount] => 5307.84
            )
    )
[1] => Array
    (
        [0] => Array
            (
                [room_rate_key] => 0|0
                [amount] => 5307.84
            )
        [1] => Array
            (
                [room_rate_key] => 0|1
                [amount] => 5246.98
            )
    )
[2] => Array
    (
        [0] => Array
            (
                [room_rate_key] => 0|1
                [amount] => 5246.98
            )
        [1] => Array
            (
                [room_rate_key] => 0|0
                [amount] => 5307.84
            )
    )
[3] => Array
    (
        [0] => Array
            (
                [room_rate_key] => 0|1
                [amount] => 5246.98
            )
        [1] => Array
            (
                [room_rate_key] => 0|1
                [amount] => 5246.98
            )
    )
)

有人能帮帮忙吗?

谢谢。


更多关于Golang中如何生成一对多关系的映射的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

是的。这是正确的。

更多关于Golang中如何生成一对多关系的映射的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


那么,创建一个适当大小的数组,然后用 mm 的副本填充它,这样不就足够了吗?在 Playground 上发布的解决方案似乎有点过度设计了。

你好 @telo_tade

根据在playground上分享的一个map,我正尝试以这样的方式生成一个新的map:主map的每个元素,即第[0]个元素,将与第[1]个元素的所有元素进行映射。

你好 @bhargavi.pise,

这一行有一个拼写错误:

for i := 0; i < 1; i++ {

其次,我不明白你所说的“从现有映射生成一对多关系映射”是什么意思。在你的示例中,我看到你有一个键为整数、值为 map[string]string 的映射:

	mm := map[int]map[string]string{
		0: map[string]string{
			"amount":        "100.00",
			"room_rate_key": "0|0",
		},
		1: map[string]string{
			"amount":        "200.00",
			"room_rate_key": "0|1",
		},
	}

它们在逻辑上意味着什么,你试图得到什么结果?

你好 @bhargavi.pise,

让我看看我理解得是否正确:你从一个名为“主映射”(main map)的初始映射开始,简称 mm:

mm := map[int]map[string]string{
	0: map[string]string{
		"amount":        "100.00",
		"room_rate_key": "0|0",
	},
	1: map[string]string{
		"amount":        "200.00",
		"room_rate_key": "0|1",
	},
}

基于这个初始映射(mm),你想要获得另一个数据结构,也是一个映射。我们称这个数据结构为“结果”。

result:= map[int][]map[int]map[string]string{
	0: []map[int]map[string]string{
		{
			0: map[string]string{
				"amount":        "100.00",
				"room_rate_key": "0|0",
			},
			1: map[string]string{
				"amount":        "200.00",
				"room_rate_key": "0|1",
			},
		},
	1: []map[int]map[string]string{
		{
			0: map[string]string{
				"amount":        "100.00",
				"room_rate_key": "0|0",
			},
			1: map[string]string{
				"amount":        "200.00",
				"room_rate_key": "0|1",
			},
		},
	2: []map[int]map[string]string{
		{
			0: map[string]string{
				"amount":        "100.00",
				"room_rate_key": "0|0",
			},
			1: map[string]string{
				"amount":        "200.00",
				"room_rate_key": "0|1",
			},
		},
	3: []map[int]map[string]string{
		{
			0: map[string]string{
				"amount":        "100.00",
				"room_rate_key": "0|0",
			},
			1: map[string]string{
				"amount":        "200.00",
				"room_rate_key": "0|1",
			},
		},
	},
}

这是对“结果”的正确定义吗?你能发布一下“结果”的 Golang 定义吗?这有助于让事情更清晰。

在Go中实现一对多映射,可以使用map嵌套切片。根据你的需求,这里是一个实现示例:

package main

import (
	"fmt"
)

type RoomRate struct {
	RoomRateKey string
	Amount      float64
}

func main() {
	// 原始数据
	roomRates := [][]RoomRate{
		{
			{"0|0", 5307.84},
			{"0|1", 5246.98},
		},
		{
			{"0|0", 5307.84},
			{"0|1", 5246.98},
		},
		{
			{"0|0", 5307.84},
			{"0|1", 5246.98},
		},
	}

	// 创建一对多映射:第一个位置的元素映射到后续所有位置的元素
	result := make(map[int][]RoomRate)
	
	// 获取第一个位置的所有元素
	firstPosition := roomRates[0]
	
	// 为第一个位置的每个元素创建映射
	for i := 0; i < len(firstPosition); i++ {
		var relatedRates []RoomRate
		
		// 遍历后续所有位置
		for pos := 1; pos < len(roomRates); pos++ {
			// 将后续位置的每个元素都添加到映射中
			for j := 0; j < len(roomRates[pos]); j++ {
				relatedRates = append(relatedRates, roomRates[pos][j])
			}
		}
		
		result[i] = relatedRates
	}

	// 打印结果
	for key, values := range result {
		fmt.Printf("[%d] => \n", key)
		for i, rate := range values {
			fmt.Printf("    [%d] => RoomRate{RoomRateKey: %s, Amount: %.2f}\n", 
				i, rate.RoomRateKey, rate.Amount)
		}
	}
}

如果你需要更具体的笛卡尔积关系(每个第一个位置的元素与后续每个位置的每个元素配对),可以使用这个版本:

package main

import (
	"fmt"
)

type RoomRate struct {
	RoomRateKey string
	Amount      float64
}

func main() {
	roomRates := [][]RoomRate{
		{
			{"0|0", 5307.84},
			{"0|1", 5246.98},
		},
		{
			{"0|0", 5307.84},
			{"0|1", 5246.98},
		},
		{
			{"0|0", 5307.84},
			{"0|1", 5246.98},
		},
	}

	// 使用字符串作为键的一对多映射
	result := make(map[string][]RoomRate)

	// 处理第一个位置
	for i, firstRate := range roomRates[0] {
		key := fmt.Sprintf("first_%d", i)
		var pairs []RoomRate
		
		// 与后续每个位置的每个元素建立关系
		for pos := 1; pos < len(roomRates); pos++ {
			for _, rate := range roomRates[pos] {
				pairs = append(pairs, rate)
			}
		}
		
		result[key] = pairs
	}

	// 输出结果
	for key, rates := range result {
		fmt.Printf("%s:\n", key)
		for i, rate := range rates {
			fmt.Printf("  [%d] %s: %.2f\n", i, rate.RoomRateKey, rate.Amount)
		}
	}
}

如果你需要生成所有可能的组合关系(类似笛卡尔积),这个版本可能更符合你的需求:

package main

import (
	"fmt"
)

type RoomRate struct {
	RoomRateKey string
	Amount      float64
}

type Pair struct {
	First  RoomRate
	Second RoomRate
}

func main() {
	roomRates := [][]RoomRate{
		{
			{"0|0", 5307.84},
			{"0|1", 5246.98},
		},
		{
			{"0|0", 5307.84},
			{"0|1", 5246.98},
		},
		{
			{"0|0", 5307.84},
			{"0|1", 5246.98},
		},
	}

	// 存储所有配对关系
	var allPairs []Pair

	// 第一个位置的每个元素与后续每个位置的每个元素配对
	for _, firstRate := range roomRates[0] {
		for pos := 1; pos < len(roomRates); pos++ {
			for _, secondRate := range roomRates[pos] {
				allPairs = append(allPairs, Pair{
					First:  firstRate,
					Second: secondRate,
				})
			}
		}
	}

	// 按第一个元素分组的一对多映射
	grouped := make(map[RoomRate][]RoomRate)
	for _, pair := range allPairs {
		grouped[pair.First] = append(grouped[pair.First], pair.Second)
	}

	// 输出分组结果
	fmt.Println("Grouped one-to-many mapping:")
	for first, seconds := range grouped {
		fmt.Printf("\nFirst: %s (%.2f)\n", first.RoomRateKey, first.Amount)
		for i, second := range seconds {
			fmt.Printf("  [%d] -> %s: %.2f\n", i, second.RoomRateKey, second.Amount)
		}
	}
}

这些示例展示了在Go中创建一对多映射的不同方法,你可以根据具体需求选择合适的方式。

回到顶部