Обновить существующий элемент массива с помощью jsonnet

Я использую jsonnet для чтения значения, состоящего из массива. Я хочу изменить первый элемент в этом массиве, чтобы добавить значение. Структура данных выглядит так:

{
   "my_value": [
      {
         "env": "something"
      },
      {
         "var": "bar"
      }
   ]
}

Я хочу добавить значение к my_value[0]. Как я могу сослаться на это в jsonnet?


person jaxxstorm    schedule 09.07.2018    source источник


Ответы (3)


Возможный подход с использованием https://jsonnet.org/ref/stdlib.html#mapWithIndex как показано ниже:

$ cat foo.jsonnet 
local my_array = [
  {
    env: "something",
  },
  {
    var: "bar",
  },
];
local add_by_idx(idx) = (
  if idx == 0 then { extra: "stuff" } else {}
);
std.mapWithIndex(function(i, v) v + add_by_idx(i), my_array)

$ jsonnet foo.jsonnet 
[
   {
      "env": "something",
      "extra": "stuff"
   },
   {
      "var": "bar"
   }
]
person jjo    schedule 10.07.2018

Вы можете комбинировать super с нарезкой массива jsonnet в стиле python:

{
   "my_value": [
      {
         "env": "something"
      },
      {
         "var": "bar"
      }
   ]
} 
+ 
{
  "my_value": [
    super.my_value[0] + {
      "env_2": "something_else"
    },
  ] + super.my_value[1:]
}

Результаты в:

{
   "my_value": [
      {
         "env": "something",
         "env_2": "something_else"
      },
      {
         "var": "bar"
      }
   ]
}
person muxmuse    schedule 22.05.2020
comment
не уверен, почему за это не проголосовали больше, это, безусловно, самое простое решение. - person Abu Belal; 16.07.2020

Лучший подход IMO: преобразование array в object для упрощения перегрузки, затем ab-использование того факта, что jsonnet обрабатывает объекты путем альфа-сортировки своих ключей:

$ cat foo.jsonnet
local array_a = [
  { env: "something" },
  { var: "bar" },
];

local array_b = [
  {},
  { extra: "stuff" },
];

// "Standarize" index key string as "%06d"
local _idx(i) = ("%06d" % [i]);

// Convert array [elem1, elem2, ...] to object as { 000000: elem0, 000001: elem1, ...}
local _to_obj(a) = std.foldl(
  function(x, y) x + y,
  std.mapWithIndex(function(i, v) { [_idx(i)]: v }, a),
  {}
);

local _to_array(obj) = [obj[k] for k in std.objectFields(obj)];

_to_array(std.mergePatch(_to_obj(array_a), _to_obj(array_b)))

$ jsonnet foo.jsonnet 
[
   {
      "env": "something"
   },
   {
      "extra": "stuff",
      "var": "bar"
   }
]
person jjo    schedule 12.11.2018