Open rmetzler opened 2 years ago
I also created a workaround as a partial, but I would rather have the function in Go. https://gist.github.com/rmetzler/bc9401874553724afb4341d31ad2c427
include "flatten" (list $input1 $input2 ...)
This named template takes a list with possible nested lists and flattens it into a 1-dimensional list (vector).
NOTE: Scalars or dictionaries (dict) are not modified.
This named template takes an input list of lists, flattens it, and converts it into a minified JSON string. If the input is a string, the template attempts to parse it as YAML. If the input is not a list, it’s wrapped into list. It then iterates over each item in the input list. If an item is a list, the template flattens it and appends it to a new list. If an item is not a list, it is appended to the new list. Finally, the template converts the new list into a JSON format.
$inputX
can be:
list
string
(representing a list as YAML)any
A normalized, minified JSON string representing the flattened list.
{{- $nestedList := (list "a" "b" 1 true (list "c" (list "d" 1) "e") (dict "f" "g" "h" 2) (list "c" (list (list "c" (list "d" 1) "e") 1) "e")) -}}
{{- $flatList := include "flatten" $nestedList -}} # $flatList is now: ["a","b",1,true,"c","d",1,"e",{"f":"g","h":2},"c","c","d",1,"e",1,"e"]
{{- define "flatten" -}}
{{- /* Assign the input value to $inputList. If the input is nil, assign an empty list to $inputList */ -}}
{{- $inputList := . | default (list) -}}
{{- /* If $inputList is a (string), try to parse it as YAML */ -}}
{{- if $inputList | kindIs "string" -}}
{{- /* Use printf-wrap method to overcome the issue with the Helm's fromYaml function */ -}}
{{- $inputList = (printf "result: %v" ($inputList | nindent 2) | fromYaml).result -}}
{{- end -}}
{{- /* If $inputList is not (list), convert it to (list) */ -}}
{{- if ($inputList | kindIs "slice" | not) -}}
{{- $inputList = (list $inputList) -}}
{{- end -}}
{{- /* Initialize an empty list $newList */ -}}
{{- $newList := (list) -}}
{{- /* Iterate over each item in $inputList */ -}}
{{- range $idx, $listItem := $inputList -}}
{{- /* If the item is (list) ... */ -}}
{{- if ($listItem | kindIs "slice") -}}
{{- /* ... flatten it (recursively) ... */ -}}
{{- $flattenedList := (printf "result: %v" (((include "flatten" $listItem) | nindent 2)) | fromYaml).result -}}
{{- /* ... and concat it to $newList */ -}}
{{- $newList = concat $newList $flattenedList -}}
{{- /* If the item is not an (list) ... */ -}}
{{- else -}}
{{- /* ... append it to $newList */ -}}
{{- $newList = append $newList $listItem -}}
{{- end -}}
{{- end -}}
{{- /* Convert $newList to minified JSON string and return */ -}}
{{- $newList | mustToJson -}}
{{- end -}}
In my Helm charts, I would like to reuse lists. The main issue is the syntax for this and while it' simple to do so for YAML hashes, it's not as simple for lists. So I came up with the notation of writing something like:
This creates a nested list
list2
and theflatten
function should turn it into a flat list which looks like: