代码之家  ›  专栏  ›  技术社区  ›  jaxxstorm

用JSONNET更新现有数组元素

  •  2
  • jaxxstorm  · 技术社区  · 6 年前

    我使用jsonnet读取一个由数组组成的值。我想修改数组中的第一个元素以添加值。数据结构如下:

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

    我想增加一个值 my_value[0] 是的。我怎么能在jsonnet中引用它呢?

    2 回复  |  直到 6 年前
        1
  •  4
  •   jjo    6 年前

    一种可能的方法 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"
       }
    ]
    
        2
  •  0
  •   jjo    6 年前

    IMO更好的方法:转换 array object 为了更容易重载,ab使用jsonnet通过alpha排序其键来处理对象:

    $ 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"
       }
    ]
    
    推荐文章