#open-policy-agent #rego
#open-policy-agent #rego
Вопрос:
Как мне объединить массив объектов в один объект в rego
?
Я знаю, как объединить два объекта, но как мне выполнить цикл по массиву объектов?
Этот пример работает, но он (очевидно) не масштабируется 😉
a := [{"test1": "123"}, {"test2": "456"}, {"test3": "789", "test4": "012"}]
b := {
"my-property": object.union(object.union(a[0], a[1]), a[2])
}
Ожидаемый результат:
{
"test1": "123",
"test2": "456",
"test3": "789",
"test4": "012"
}
Спасибо!
Каспер
Ответ №1:
TLDR; предполагая, что ключи объекта уникальны (как в вашем примере), вы можете просто использовать понимание:
b := {k: v |
some i, k
v := a[i][k]
}
Поскольку переменная i
используется только один раз, вы можете заменить ее на _
, чтобы избежать необходимости придумывать имя:
b := {k: v |
some k
v := a[_][k]
}
Если ключи объекта не уникальны, это немного сложнее, потому что вам нужно решить, как разрешать конфликты, когда два объекта содержат один и тот же ключ с разными значениями. То, как вы решите разрешить конфликты, будет зависеть от варианта использования. Один из способов разрешить их — просто сгруппировать значения по их ключам. Например:
# the 'test2' key appears in more than one object with a different value
a := [{"test1": "123"}, {"test2": "456"}, {"test3": "789", "test2": "012"}]
Чтобы сгруппировать значения по ключам, вы можете написать вложенное понимание:
{k: vs |
# for each key 'k'
some k
conflicting[_][k]
# find all values for key 'k' and group as a set
vs := {v | v := conflicting[_][k]}
}
Вывод:
{
"test1": [
"123"
],
"test2": [
"012",
"456"
],
"test3": [
"789"
]
}
Комментарии:
1. Потрясающе! Я пробовал с пониманием объекта, но часть, которую мне не хватало, была
k: v
-part . Еще раз спасибо!