maps allow direct access to fields of stored objects by name, often you get a list back and want to convert that to a map to later address fields or add new fields. also extracting fields from multiple data files building up one object for later use …
due to the fact, that a map is immutable and you cannot add elements in one run using a single dict statement you will have to merge
that. This needs a copy and is quite expensive especially with larger datasets.
seen often in code it is imho a common design pattern I to collect a set of options to a dict.
pushing all that attributes to a slice using append and later convert the slice to a map imho is much faster. So it might be mostly a thing for large datasets or large sites that do that very often
I found that using the SetInMap approach from above is about 3 times faster than the merge for a list of 50 objects 2times for 30 (just timer.Stop for a run of hugo )
moving such operation to the internals would I guess gain more pace also for lower numbers…
so it would look this
$map = {
"a": 1,
"b": [ 2 3 4 ]
"c": {
"d": 5
"e": [6 7 8]
}
}
ideally with dotted access with to possibility to use index $map "a.c.e"
real life
get Link from Response header : GetRemote: 0.143.0-dev
{{ define "partials/getLinks" }}
{{ $links := dict }}
{{ with try (index (index .Data.Headers "Link") 0) }}
{{ with .Err }}
{{ warnf "OOPS> get links %v" . }}
{{ else }}
{{ with .Value }}
{{ range split . "," }}
{{ with split . ";" }}
{{ $link := trim (index . 0) "<> " }}
{{ $rel := index (split (index . 1) `"`) 1 }}
{{ $links = merge $links (dict $rel $link) }}
{{ end }}
{{ end }}
{{ else }}
{{ warnf "NO VALUE> %v" . }}
{{ end }}
{{ end }}
{{ else }}
{{ warnf "NO LINK HERE %v" . }}
{{ end }}
{{ return $links }}
{{ end }}
some more pseude code… examples
tl;tr;
# dict
$attrs := dict
range $name := get some attributes {
$value := calculate attribute vale maybe with other data or a partial
$attrs = merge $attrs (dict $name $value)
}
# slice
$attrs = slice
range $name := get some attributes {
$value := calculate attribute vale maybe with other data or a partial
$attrs = $attrs | append $name $value
}
$attrs := dict $attrs <-- impossible
the above is a common design pattern I found often to collect a set of options to a dict
# parse a list of objects and create a map (for direct access skipping where)
$dict = dict
range $objects {
$dict = merge $dict (dict .key .)
}
# $map := cast.ObjectSliceToMapWithKey "KEYFIELD" $slice
# or create a list of properties (eg from a .properties file
range $properties {
$prop = split '=' .
$props = merge $props (dict $prop[0] $prop[1])
}
# What about a mapbuilder without need to create a new map always ;-)
# $map = mapbuilder.Start
# range $properties {
$prop = split '=' .
$map.Add $prop[0] $prop[1]
}
$map.End
looks like Go 1.23 has a maps package for that