...">

Golan card with multiple keys per cost

Consider the following XML data structure:

<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>

      

Since my XML data structure / file can potentially scale up to 10,000, or perhaps 100,000+ media items, I need to be able to access the individual items, in the parsed Go map (or which structure to use here?), For example we do with map[key]type

- but me one needs to be able to use either a url or an id as a key and I can't figure out how to create a map with two keys pointing to the same value.

From the parsed XML data structure above, I need to parse it in Go and store it as a type:

map[string, string]MediaItem

      

If the keys need to be url and id, so I could get the element with id 1 doing myMap["1"]

or myMap["media/somefolder/pic1.jpg"]

. Both should return a matching one MediaItem

.)

I can't get my head around how to implement this, or maybe there is a better way to achieve the same?

+3


source to share


1 answer


Staying with the type map

, you can use 2 (3) different solutions:

With 2 cards

The simplest would be to build 2 maps, 1 where the keys are URLs, and 1 where the keys are IDs:

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

      

Note that you must store pointers instead of structures to avoid duplicate values.

If you need MediaItem

by id:

mi := byIdMap[id]

      

Similarly for the URL:

mi2 := byUrlMap[url]

      

With key prefixes

Another option might be to prefix the actual key values, but this is not as efficient, but you end up with only one map.



For example, you can prefix the url keys with "url:"

and ids with "id:"

and store, of course, the pointer value for the url and id keys, for example:

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

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

      

And getting the element:

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

      

Using the "as-is" keys

This is something like "key-prefixed": if you have a guarantee that URLs and IDs will never be the same (this means that you will never have an ID that matches another URL and vice versa ), you can simply use both keys without prefixes and set them to the same value (pointer).

The purpose of the key prefixes was to make sure that the final url key will never be the same as the final key of the key (achieved by using different prefixes for the two types of keys). But if that condition is naturally true (for example, the value string

for a numeric identifier will never be a valid URL), then we really don't need the prefixes:

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

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

      

And getting the element:

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

      

+9


source







All Articles