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.10/language/functions/flatten/