flatten Функция
flatten принимает список и заменяет любые элементы, являющиеся списками, уплощенной последовательностью их содержимого.
Примеры
> flatten([["a", "b"], [], ["c"]]) ["a", "b", "c"]
Если какие-либо вложенные списки также содержат непосредственно вложенные списки, они тоже уплощаются рекурсивно:
> flatten([[["a", "b"], []], ["c"]]) ["a", "b", "c"]
Списки, вложенные косвенно, например в отображениях, не уплощаются.
Уплощение вложенных структур для for_each
Языковые конструкции ресурса for_each и блока dynamic требуют значения коллекции, содержащего по одному элементу для каждого повторения.
Иногда входная структура данных изначально не имеет подходящей формы для использования в аргументе for_each, и flatten может быть полезной вспомогательной функцией для преобразования вложенной структуры данных в плоскую.
Например, рассмотрим модуль, который объявляет переменную следующим образом:
variable "networks" {
type = map(object({
cidr_block = string
subnets = map(object({ cidr_block = string }))
}))
}Описанный выше способ подходит для моделирования объектов, которые естественным образом образуют дерево, например сетей верхнего уровня и их подсетей. Для повторения сетей верхнего уровня можно напрямую использовать эту переменную, поскольку она уже имеет форму, в которой результирующие экземпляры соответствуют элементам отображения один к одному:
resource "aws_vpc" "example" {
for_each = var.networks
cidr_block = each.value.cidr_block
}Однако, чтобы объявить все подсети с помощью одного блока resource, сначала необходимо уплощить структуру и получить коллекцию, в которой каждый элемент верхнего уровня представляет одну подсеть:
locals {
# flatten ensures that this local value is a flat list of objects, rather
# than a list of lists of objects.
network_subnets = flatten([
for network_key, network in var.networks : [
for subnet_key, subnet in network.subnets : {
network_key = network_key
subnet_key = subnet_key
network_id = aws_vpc.example[network_key].id
cidr_block = subnet.cidr_block
}
]
])
}
resource "aws_subnet" "example" {
# local.network_subnets is a list, so we must now project it into a map
# where each key is unique. We'll combine the network and subnet keys to
# produce a single unique key per instance.
for_each = {
for subnet in local.network_subnets : "${subnet.network_key}.${subnet.subnet_key}" => subnet
}
vpc_id = each.value.network_id
availability_zone = each.value.subnet_key
cidr_block = each.value.cidr_block
}В результате создается один экземпляр подсети для каждого объекта подсети, при этом сохраняются связи между подсетями и содержащими их сетями.
Связанные функции
-
setproductнаходит все комбинации нескольких списков или множеств значений; эта функция также может быть полезна при подготовке коллекций для использования с конструкциямиfor_each.
Copyright (c) The OpenTofu Authors
Copyright (c) 2014 HashiCorp, Inc.
Mozilla Public License, version 2.0
https://opentofu.org/docs/v1.12/language/functions/flatten/