【问题标题】:Update an existing array element with jsonnet使用 jsonnet 更新现有数组元素
【发布时间】:2018-07-09 23:41:38
【问题描述】:

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

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

我想为my_value[0] 添加一个值。如何在 jsonnet 中引用它?

【问题讨论】:

    标签: jsonnet


    【解决方案1】:

    你可以将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"
          }
       ]
    }
    

    【讨论】:

    • 不知道为什么这没有被更多投票,这是迄今为止最简单的解决方案。
    【解决方案2】:

    使用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"
       }
    ]
    

    【讨论】:

      【解决方案3】:

      IMO 更好的方法:将 array 转换为 object 以便于重载,然后使用 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"
         }
      ]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-10
        • 1970-01-01
        • 2017-07-03
        • 1970-01-01
        相关资源
        最近更新 更多