Merge maps together with different structure

I have two maps in the following format:

nodes = {
  node1 = {
    item0 = string
    item1 = list
    item2 = list
    item3 = list
  }
  node2 = {
    ...
  }
  node3 = {
  ...
  }
}

and module output:

nodes = {
  node1 = list
  node2 = list
  node3 = list
}

How can I, or is there a way to take the outputs from the second map and merge them with the first map? I’ve been playing with some for expressions but cannot find the correct way.

It would be extremely helpful if I could take the dynamic outputs from the second map and merge it into the first – I figure the best way to process this would be in a locals block.

Hi @meraxes!

I’m afraid I’m not really sure what it would mean to merge lists into objects/maps as you’ve shown here. Perhaps it would help to say more about the underlying requirement that you’re trying to meet here, rather than the solution you attempted, and then I might be able to give better advice.

If your meaning of “merge” here was to add a new attribute to each of the objects in the first structure which takes the values from the second structure, then the following could potentially do that, if we assume that nodes_1 is your first structure and nodes_2 is your second:

locals {
  merged = tomap({
    for k in setunion(keys(local.nodes_1), keys(local.nodes_2)) :
    k => merge(
      try(local.nodes_1[k], {}),
      { new_thing = try(local.nodes_2[k], null) },
    )
  })
}

Here I’ve used setunion(keys(local.nodes_1), keys(local.nodes_2)) to produce a set of all of the distinct keys across both of the maps, thus ensuring that all of the elements of both maps can be represented in the result.

Then for each of those keys I used merge to combine together the object from nodes_1 with a new single-attribute object containing the value from nodes_2. In both cases I used try to handle situations where the key names aren’t consistent between the two maps, providing fallback values to use instead.

Does that seem something like what you wanted? If not, it’d help to say a little more about what you’re trying to achieve and, ideally, in what way the above idea fails to meet that requirement. Thanks!

2 Likes