我是Go语言的新手。我正在努力跟随用例。
我想在地图中存储会话ID(字符串)和reqeust No(字符串)以进行重复检查。当地图中没有条目时,它应该创建一个条目,否则它应该返回一个标记,表明条目已经存在。
var geocoder;
var map;
function initialize() {
var center = new google.maps.LatLng(51.97559, 4.12565);
map = new google.maps.Map(document.getElementById('map'), {
center: center,
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var bounds = new google.maps.LatLngBounds();
var start = ['42.81405, 12.4886861111', '32.7994444444, 20.506775', '44.8062644989, 20.5005495758'];
var end = ['47.81405, 18.4886861111', '33.7994444444, 21.506775', '39.8062644989, 16.5005495758'];
var paths = [];
for (var i=0; i < end.length; i++){
var startCoords = start[i].split(",");
var startPt = new google.maps.LatLng(startCoords[0],startCoords[1]);
var endCoords = end[i].split(",");
var endPt = new google.maps.LatLng(endCoords[0],endCoords[1]);
paths.push([startPt, endPt]);
bounds.extend(startPt);
bounds.extend(endPt);
}
map.fitBounds(bounds);
var polyline = new google.maps.Polygon({
paths: paths,
strokeColor: 'red',
strokeWeight: 2,
strokeOpacity: 1
});
polyline.setMap(map);
}
google.maps.event.addDomListener(window, "load", initialize);
我面临的问题是每次调用函数时都会重写该值。 我在这里做错了什么?
答案 0 :(得分:1)
如果给定会话ID的映射尚不存在,则只需创建内部映射(会话映射)的值(如果给定的请求编号不在其中,则不 ),否则你清除之前存储的任何请求编号。
由于您使用bool
作为内部映射(会话映射)的值类型,您可以利用它来编写更简单的代码(使用不在其中的键索引映射将产生零值值类型,false
类型的bool
,正确告知密钥不在其中):
func chkDuplicate(m map[string]map[string]bool, sess string, Reqno string) bool {
sessMap := m[sess]
if sessMap == nil {
m[sess] = map[string]bool{Reqno: true}
return false
}
if sessMap[Reqno] {
return true
}
sessMap[Reqno] = true
return false
}
测试它:
func main() {
mySessionData := make(map[string]map[string]bool)
for _, reqNo := range []string{"1", "2", "3", "2", "4"} {
ret := chkDuplicate(mySessionData, "session1", reqNo)
fmt.Println(ret, mySessionData)
}
delete(mySessionData, "session1")
fmt.Println(mySessionData)
}
输出(在Go Playground上尝试):
false map[session1:map[1:true]]
false map[session1:map[1:true 2:true]]
false map[session1:map[1:true 2:true 3:true]]
true map[session1:map[2:true 3:true 1:true]]
false map[session1:map[2:true 3:true 4:true 1:true]]
map[]
请注意bool
- 尽管可能很小 - 确实需要内存。由于我们可以查询键是否在映射中,因此我们可以选择使用不需要内存的值类型,例如空结构(struct{}
)。有了它,它可能看起来像这样:
func chkDuplicate(m map[string]map[string]struct{}, sess string, Reqno string) bool {
sessMap := m[sess]
if sessMap == nil {
m[sess] = map[string]struct{}{Reqno: struct{}{}}
return false
}
if _, ok := sessMap[Reqno]; ok {
return true
}
sessMap[Reqno] = struct{}{}
return false
}
测试和结果(几乎)相同,在Go Playground上尝试。
警告:从示例中可以看出,您希望使用它来跟踪先前是否已提供(Web)请求,其中通常涉及多个goroutine。此解决方案对于并发使用不安全。
答案 1 :(得分:0)
sess变量总是等于session1,因此您只需覆盖关键session1的值。你必须有无法区分的密钥。
如果您只想检查重复项,请执行以下操作:
package main
import "fmt"
func main() {
mySessionData := make(map[string]bool)
chkDuplicate(mySessionData, "session1", "1")
chkDuplicate(mySessionData, "session1", "1")
chkDuplicate(mySessionData, "session2", "1")
fmt.Println(mySessionData) # two keys printed
}
func chkDuplicate(m map[string]bool, sess string, Reqno string) bool {
key := fmt.Sprintf("%s-%s", sess, Reqno)
_, found := m[key]
if !found {
m[key] = true
}
return !found
}
答案 2 :(得分:0)
使用结构键而不是多级地图通常更简单: https://play.golang.org/p/WFlGi1rrVOm