每个值有多个键的Golang地图

时间:2015-05-29 12:44:13

标签: dictionary go

考虑以下XML数据结构:

<MediaItems>
    <item url="media/somefolder/pic1.jpg" id="1">
        <groups>
            <group>1</group>
            <group>2</group>
        </groups>
    </item>
    <item url="media/somefolder/pic2.jpg" id="2">
        <groups>
            <group>3</group>
            <group>7</group>
        </groups>
    </item>
</MediaItems>

由于我的XML数据结构/文件可能扩展到10000或者可能超过100000个媒体项元素,我需要能够在解析的Go地图(或者在这里使用什么结构?)中访问各个项目,例如我们使用map[key]type - 但我需要能够使用url或id作为键,我无法弄清楚如何使用指向相同值的2个键创建地图。

从上面解析的XML数据结构中,我需要在Go中解析它并将其存储在如下类型中:

map[string, string]MediaItem

如果密钥应为url和id,那么我就可以获取ID为myMap["1"]myMap["media/somefolder/pic1.jpg"]的项目。两者都应该返回相应的MediaItem。)

我无法解决如何实现这个问题,或者有更好的方法来实现这一目标?

2 个答案:

答案 0 :(得分:9)

保持map类型,您可以使用2(3)种不同的解决方案:

有2张地图

最简单的方法是构建2个地图,1代表密钥是网址,1代表密钥是ID:

var byUrlMap map[string]*MediaItem
var byIdMap map[string]*MediaItem

请注意,您应该存储指针而不是结构,以避免重复值。

如果您需要MediaItem ID:

mi := byIdMap[id]

同样通过网址:

mi2 := byUrlMap[url]

带有密钥前缀

另一个选项可以是为实际键值添加前缀,但这不是那么有效,但结果是,您只有一个地图。

例如,您可以使用"url:"前缀URL键,使用"id:"添加ID,并为url和id键存储相同的指针值,例如:

var miMap = make(map[string]*MediaItem)

mi := &MediaItem{}
miMap["url:http://something"] = mi
miMap["id:1"] = mi

获得元素:

mi2 := miMap["id:" + id]   // By id
mi3 := miMap["url:" + url] // By url

使用键&#34;原样&#34;

这类似于&#34;使用键前缀&#34;:如果您保证URL和ID永远不会相同(意味着您永远不会拥有与其他项目相同的ID&#39; ; s url,反之亦然),你可以简单地使用没有前缀的两个键,并为它们设置相同的值(指针)。

密钥前缀的目的是确保最终的url密钥永远不会与最终的id密钥相同(通过对这两种类型的密钥使用不同的前缀来实现)。但如果这种情况自然正确(例如,数字ID的string值永远不会是有效的网址),我们就不需要这些前缀:

var miMap = make(map[string]*MediaItem)

mi := &MediaItem{}
miMap["http://something"] = mi
miMap["1"] = mi

获得元素:

mi2 := miMap[id]  // By id
mi3 := miMap[url] // By url

答案 1 :(得分:6)

更好的解决方案是使用带有两个字段的struct作为键:

type key struct {
    url string
    id  int
}

m := make(map[key]MediaItem)
m[key{url: "http://...", id: 2}] = MediaItem{}