How to flatten 2-dim lists by "column" in terraform?

According to the https://www.terraform.io/docs/configuration/functions/flatten.html , we could flatten 2-dim lists by “row”.

> flatten([["a", "b"], ["c","d"], ["e"]])
["a", "b", "c", "d", "e"]

The question is row to flatten 2-dim lists by “column” in terraform ?

input:

> [["a", "b"], ["c","d"], ["e"]]

pretty print:

[
    ["a","b"], 
    ["c","d"], 
    ["e"]
]


output:

["a", "c", "e", "b", "d"]

i.e. “a”, “c”, “e” is the first column. “b”, “d” is the second column

It is easy in python or java language, but I can not search on the google how to implement it in Terraform.

Thank you !

Hi @zhfkt,

There’s no built-in function for that operation, but we can compute it using a for expression along with some other functions:

variable "input" {
  type    = list(list(string))
  default = [["a", "b"], ["c","d"], ["e"]]
}

locals {
  max_length = max([for l in var.input : length(l)]...)
  rows = [
    for idx in range(local.max_length) : [
      for l in var.input : l[idx] if idx < length(l)
    ]
  ]
  flat = flatten(local.rows)
}

output "rows" {
  value = local.rows
}

output "flat" {
  value = local.flat
}

I would generally suggest treating complex computations/transformations like this as a last resort in Terraform, because it isn’t really in the spirit of having a configuration that straightforwardly declares what should exist, but the language is powerful enough to do things like this when you need to.

Hi @apparentlymart

Thank you for the detailed explanation ! I just start to learn terraform and found it is totally different from the common language like java and python. So sometimes some easy functionality in java and python may be not easily implemented in terraform. From my initial feeling, I just think the design philosophy of the terraform tends to do everything in one sentence like the list comprehension in python , which will also make users translate the “Procedure Oriented” code in their brain to the terraform code.

Thank you for helping !

Hi @apparentlymart

I just try this code for another variable and seems the following error reported:

Error: Invalid expanding argument value

  on instance_data.tf line 37, in locals:
  37:   instance_fd_max_row_length = max([for l in local.instance_raw_fd_ad_list : length(l)]...)

The expanding argument (indicated by ...) must be of a tuple, list, or set
type.

I searched on the github and seems there was a bug in the lower version of terrafrom :

Argument expansion error in output expression during validation walk · Issue #22404 · hashicorp/terraform · GitHub (In fact, this bug is found by you)

I used the workaround mentioned in the above link, and it works:

 max(flatten([[for l in local.instance_raw_fd_ad_list : length(l)]])...)

Just let you know. Thank you !