数组中的 Jsonnet 对象理解

Jsonnet object comprehension in array

我知道如何在 Jsonnet 中像这样进行数组理解,使用 for 循环,数组中的一个对象将循环使用我定义的所有值:

local values = [
  'foo',
  'bar',
  'foobar',
];
{
list: 'movies', 
items: [
  {
      title: 'title',
      language: 'english',
      metadata: {
        author: 'god',
        value: v,
      },
    },
    for v in values
  ],
}

输出:

{
   "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"
}

我现在想像这样对数组中的多个对象执行此操作:

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,
      },
    },
  ],
}

我需要做什么才能得到以下输出?所以三个对象中的每一个都得到三个值

{
   "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"
}

在下面粘贴两个可能的解决方案,它们各有优缺点(取决于您需要进一步自定义最终 items 数组):

1) 混合数组,理解中的值为“placement”

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) 创建 movies(v) 输出 3 语言数组的函数,在 values 上聚合并展平它

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
  ]),
}