gpt4 book ai didi

go - 为什么我的 map 合并功能会合并所有内容?

转载 作者:行者123 更新时间:2023-12-01 22:24:57 25 4
gpt4 key购买 nike

我有一个相当简单的 Go 程序,它可以确定某人的日程安排是否有重叠。本质上这就是它的作用:

我们有 3 个事件,比如说杂货店:

            day   0  1  2  3  4  5     
apple sale [-----------]
banana sale [--------]
pickle sale [-------------]

这是我的代码:
package main

import (
"fmt"
)

type event struct {
start int
end int
groups map[string]bool
}

func main(){
//Create Events
campaigns := []event{
event{
start: 0,
end: 4,
groups: map[string]bool{
"apple sale": true,
},
},
event{
start: 2,
end: 5,
groups: map[string]bool{
"banna sale": true,
},
},
event{
start: 3,
end: 10,
groups: map[string]bool{
"pickle sale": true,
},
},
}

fmt.Printf("\n-------------\n| Events |\n-------------\n\n")

for _, c := range campaigns {
fmt.Printf("Name: ")
for name, _ := range c.groups {
fmt.Printf("%v, ", name)
}
fmt.Printf("\nStart:%v\nEnd:%v\n\n", c.start, c.end)
}

overlaps := recursiveOverlaps(campaigns, make([]event, 0))

fmt.Printf("\n-------------\n| Overlaps |\n-------------\n\n")

for _, c := range overlaps {
fmt.Printf("Events: ")
for name, _ := range c.groups {
fmt.Printf("%v, ", name)
}
fmt.Printf("\nStart:%v\nEnd:%v\n\n", c.start, c.end)
}
}

func recursiveOverlaps(events []event, overlaps []event) []event {

//pop comparisonEvent (first item in array)
comparisonEvent, events := events[len(events)-1], events[:len(events)-1]


if len(events) == 0 {//check base case
return overlaps;
}

//Find overlaps
for _, eventItem := range events {

overlaping, overlapCase := overlapExists(comparisonEvent, eventItem)

if overlaping {

groups := mergeKeys(comparisonEvent.groups, eventItem.groups)

switch overlapCase {

case 1:
overlaps = append( overlaps, event{eventItem.start, eventItem.end, groups} )

case 2:
overlaps = append( overlaps, event{comparisonEvent.start, comparisonEvent.end, groups} )

case 3:
overlaps = append( overlaps, event{eventItem.start, comparisonEvent.end, groups} )

case 4:
overlaps = append( overlaps, event{comparisonEvent.start, eventItem.end, groups} )
}

//reset groups so we don't get any funny business
groups = map[string]bool{}

}
}

return recursiveOverlaps(events, overlaps)
}

func overlapExists(a event, b event) (bool, int) {

if between(a.start, a.end, b.start) && between(a.start, a.end, b.end) {
// [----------]
// [-----]
return true, 1
}

if between(b.start, b.end, a.start) && between(b.start, b.end, a.end) {
// [-----]
// [----------]
return true, 2
}

if between(a.start, a.end, b.start) {
// [----------]
// [--------------
return true, 3
}

if between(a.start, a.end, b.end) {
// [----------]
// --------------]
return true, 4
}

return false, 0
}

func between(a, b, c int) bool {
//is c between a and b?
if c > a && c < b {
return true
}
return false
}

// Given two maps merge right into left
func mergeKeys(left, right map[string]bool) map[string]bool {
for key, rightVal := range right {
left[key] = rightVal
}
return left
}


该代码几乎可以工作....但问题是,从逻辑上讲,我将其编程为仅比较两个事件。一次不是三个。然而,结果是这样的:
-------------
| Events |
-------------

Name: apple sale,
Start:0
End:4

Name: banna sale,
Start:2
End:5

Name: car sale,
Start:3
End:10


-------------
| Overlaps |
-------------

Events: banna sale, car sale, apple sale,
Start:3
End:4

Events: car sale, apple sale, banna sale,
Start:3
End:5

Events: banna sale, apple sale,
Start:2
End:4

不知何故,我认为 mergeKeys()功能正在做一些奇怪的事情。有任何想法吗?

最佳答案

好的。所以我弄清楚出了什么问题:
go中的 map 是通过引用传递的……有点。并不真地。
即使 map 前面没有指针……它们是通过引用传递的……有点。确实不是,但您可以在 this article 中了解更多信息。 , "go 中没有引用传递"和 this article , “如果 map 不是引用变量,它是什么”。我将为您提供这段摘录以澄清正在发生的事情:

A map value is a pointer to a runtime.hmap structure.


即使 map 不是通过引用而是通过值传递的……您传递给函数的原始 map 变量也会被修改。这意味着当我在 mergeKeys 函数中更改左侧 map 时,我实际上也在更改 compareEvent.groups map 。
为了解决这个问题,我创建了一个垃圾 map ,我可以对其进行变异并且不会产生任何后果:
if overlaping {

trashMap := make(map[string]bool)
for key, value := range comparisonEvent.groups {
trashMap[key] = value
}

groups := mergeKeys(trashMap, eventItem.groups)

switch overlapCase {

case 1:
overlaps = append( overlaps, event{eventItem.start, eventItem.end, groups} )

case 2:
overlaps = append( overlaps, event{comparisonEvent.start, comparisonEvent.end, groups} )

case 3:
overlaps = append( overlaps, event{eventItem.start, comparisonEvent.end, groups} )

case 4:
overlaps = append( overlaps, event{comparisonEvent.start, eventItem.end, groups} )
}
}
在我接受这个答案之前,我仍然愿意讨论和更好的解决方案。我希望这可以帮助那里的人!

关于go - 为什么我的 map 合并功能会合并所有内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60573664/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com