home

Jsonnet array operations

2024-04-24

Jsonnet is what’s used by the kube-prometheus project.

While streamlining deployment operations, I’ve had to do obviously simple things like:

The Jsonnet stdlib provides the following helpers:

I’d used these a few days ago, but today, it wasn’t working as expected. So, I go and look at the documentation? right? right??? (what fun is reading documentation when you can read the source code ._.)

There’s a clear disclaimer in the stdlib documentation:

Note that the std.set* functions rely on the uniqueness and ordering on arrays passed to them to work. This can be guaranteed by using std.set(arr). If that is not the case, the functions will quietly return non-meaningful results.

However, this won’t work for me since if I end up re-ordering the arrays, that’ll re-order a bunch of things on production that I don’t want.

Simple enough, is writing those functions myself (after complaining on twitter of course), so I ended up with 3 helpers (of which I use… 2):

{
  local id = function(x) x,
  local keySet = function(a, keyF=id)
    { [k]: true for k in std.map(keyF, a) if k != null },

  arrUnion(a, b, keyF=id)::
    local aSet = keySet(a, keyF);
    local bSet = keySet(b, keyF);
    a + std.foldl(function(acc, e) acc + (
      local key = keyF(e);
      if (key != null && std.objectHas(aSet, key)) then [] else [e]
    ), b, []),

  arrInter(a, b, keyF=id)::
    local aSet = keySet(a, keyF);
    local bSet = keySet(b, keyF);
    std.foldl(function(acc, e) acc + (
      local key = keyF(e);
      if (key != null && std.objectHas(bSet, key)) then [e] else []
    ), a, []),

  arrDiff(a, b, keyF=id)::
    local bSet = keySet(b, keyF);
    std.foldl(function(acc, e) acc + (
      local key = keyF(e);
      if (key != null && std.objectHas(bSet, key)) then [] else [e]
    ), a, []),
}

home