Dict not respecting input order

Hey there, I just ran into something troublesome for me.

I guess it may be by design, but I need to range on some items and keep the input ordering.

{{ $fields := (dict "Title" "p_title" "Type" "p_type" "Status" "p_status") }}
{{ range $index, $value := $fields}}
    {{ $index}}:{{$value}}
{{ end }}

Will output:
Status:p_status Title:p_title Type:p_type

Exemple above is overly simplified, and doesn’t illustrate the real reason behind my need for ordering.

How does the reordering works (alpha it seems) with dict and does anyone knows any way to create a dict equivalent that respects order?

Thanks

Isn’t it:

{{range pipeline}} T1 {{end}}

If the value is a map and the
keys are of basic type with a defined order (“comparable”), the
elements will be visited in sorted key order

Status:p_status Title:p_title Type:p_type

The order is by the keys (Status, Title, Type)

1 Like

Thanks! That explains the ordering.

I wish there was a way to ignore this automatic ordering for which I can’t really imagine any practical use case…

{{ $myArray := slice "Title" "p_title" "Type" "p_type" "Status" "p_status" }}
{{ if modBool (len $myArray) 2 }}
  {{ range (seq 0 2 (sub (len $myArray) 1)  )  }}
    {{ . }}:{{ index $myArray  . }}:{{ index $myArray (add . 1) }}
  {{ end }}
{{ else }}
must be even
{{ end }}
0:Title:p_title
2:Type:p_type
4:Status:p_status
1 Like

As the alternative (keeping the data structure as a Go map) would be random order, I’m not sure that would be better. But I agree.

We should do better, but I’m not sure how.

No way to make Hugo function dict use the input order as a reference and returned the map using the same ordering?

Thanks! That snippet will be useful stored in a partial!

{{ $fields := (dict "Title" "p_title" "Type" "p_type" "Status" "p_status") }}
{{ printf "#v:%#v)" $fields }}
=>
#v:map[string]interface {}{"Title":"p_title", "Type":"p_type", "Status":"p_status"})

It isn’t a go map?

Not with a map. We should investigate this, but this is not limited to dict – and maps are tighly integrated into the Go templates, so changing it to some custom data structure would break range $k, $v := constructs.

I see, creating a default ordered map and not being able to use $index and $value wouldn’t help indeed.