I know how to do Array comprehension in Jsonnet like this, with the for loop the one object in the array gets looped with all my defined values:
local values = [
'foo',
'bar',
'foobar',
];
{
list: 'movies',
items: [
{
title: 'title',
language: 'english',
metadata: {
author: 'god',
value: v,
},
},
for v in values
],
}
output:
{
"items": [
{
"language": "english",
"metadata": {
"author": "god",
"value": "foo"
},
"title": "title"
},
{
"language": "english",
"metadata": {
"author": "god",
"value": "bar"
},
"title": "title"
},
{
"language": "english",
"metadata": {
"author": "god",
"value": "foobar"
},
"title": "title"
}
],
"list": "movies"
}
I now want to do this with multiple objects in an array like this:
local values = [
'foor',
'bar',
'foorbar',
];
{
list: 'movies',
items: [
{
title: 'title',
language: 'english',
metadata: {
author: 'god',
value: v,
},
},
{
title: 'title2',
language: 'german',
metadata: {
author: 'devil',
value: v,
},
},
{
title: 'title3',
language: 'spanish',
metadata: {
author: 'chutulu',
value: v,
},
},
],
}
What to I need to do to have the following output? So every of the three objects get the three values
{
"items": [
{
"language": "english",
"metadata": {
"author": "god",
"value": "foor"
},
"title": "title1"
},
{
"language": "english",
"metadata": {
"author": "god",
"value": "bar"
},
"title": "title1"
},
{
"language": "english",
"metadata": {
"author": "god",
"value": "foorbar"
},
"title": "title1"
}
{
"language": "german",
"metadata": {
"author": "devil",
"value": "foor"
},
"title": "title2"
},
{
"language": "german",
"metadata": {
"author": "devil",
"value": "bar"
},
"title": "title2"
},
{
"language": "german",
"metadata": {
"author": "devil",
"value": "foorbar"
},
"title": "title2"
}
{
"language": "spanish",
"metadata": {
"author": "chutulu",
"value": "foor"
},
"title": "title3"
},
{
"language": "spanish",
"metadata": {
"author": "chutulu",
"value": "bar"
},
"title": "title3"
},
{
"language": "spanish",
"metadata": {
"author": "chutulu",
"value": "foorbar"
},
"title": "title3"
}
],
"list": "movies"
}
CodePudding user response:
Pasting below two possible solutions, with their own tradeoffs (depending on how further you need to customize the final items
array):
1) Mixing arrays, with value "placement" in the comprehension
local values = [
'foor',
'bar',
'foorbar',
];
local movies = [
{
title: 'title',
language: 'english',
metadata: {
author: 'god',
},
},
{
title: 'title2',
language: 'german',
metadata: {
author: 'devil',
},
},
{
title: 'title3',
language: 'spanish',
metadata: {
author: 'chutulu',
},
},
];
// Combine the `values` and `movies` arrays into `items`,
// overloading movie's metadata.value with each value,
// note the `metadata :` syntax.
{
list: 'movies',
items: [
movie { metadata : { value: value } }
for movie in movies
for value in values
],
}
2) Create movies(v)
function that outputs the 3-lang array, aggregate over values
and flatten it
local values = [
'foor',
'bar',
'foorbar',
];
local movies(v) = [
{
title: 'title',
language: 'english',
metadata: {
author: 'god',
value: v,
},
},
{
title: 'title2',
language: 'german',
metadata: {
author: 'devil',
value: v,
},
},
{
title: 'title3',
language: 'spanish',
metadata: {
author: 'chutulu',
value: v,
},
},
];
// To build the final `items` array we need to flatten
// the array-of-arrays created by the comprehension, as
// each element is indeed a 3-movies array
{
list: 'movies',
items: std.flattenArrays([
movies(v)
for v in values
]),
}