Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return the keys of dictionaries in order #407

Open
farcaller opened this issue Nov 10, 2017 · 4 comments
Open

Return the keys of dictionaries in order #407

farcaller opened this issue Nov 10, 2017 · 4 comments

Comments

@farcaller
Copy link

Using jsonnet with k8s I've noticed an interesting pattern—whenever you specify a list of key-value strings in k8s, jsonnet's objects work better. One way to use that is to map command line aruments, e.g.

args_+: {
  tls_cert: '/abc',
  tls_key: '/def',
}

becomes

--tls-cert=/abc --tls-key=/def

One problem with that approach is that jsonnet sorts all the keys, thus making it very hard to deal with situations when key order is important.

I'd like to see a mechanism to turn objects into what's basically an OrderedDict of python.

@sparkprime
Copy link
Contributor

I think this goes against the spirit of JSON quite a lot. Having an ordered dict type would be a fairly minor improvement in expressiveness compared to forcing people to use lists of pairs (or lists of singleton objects).

args_+: [
  { tls_cert: '/abc' },
  { tls_key: '/def' },
]

@duggan
Copy link

duggan commented Apr 12, 2018

Could this be reconsidered? I've got a large collection of CloudFormation templates to work with, and a lot of different people working on them. CloudFormation's preferred formatting is a "logical" order, which is not alphanumeric.

It would make transitioning to Jsonnet easier if I could preserve the general ordering of the keys so that the resulting artifacts can be read the same way as their not-yet-converted counterparts. As it is, changesets are tricky to review and the resulting artifact has an unexpected format, making it more difficult to read.

@sbarzowski
Copy link
Collaborator

sbarzowski commented Apr 12, 2018

Hmmm... One way to handle this use case that would be to add a hidden __field_order field, which is an array of object keys. The json could then have fields listed in the order determined by this field. If __field_order was provided explicitly it could even be done without changes to the interpreter (using custom manifester) - it's on the same level as outputting canonical yaml.

So for example:

{
     a: {},
     b: {},
     c: {
          'test': 123
          'aaa': 123
          __field_order:: ['test', 'aaa']
     },
     __field_order:: ['c', 'b', 'a']
}

could produce the following json:

{
     "c": {
          "test": 123,
          "aaa":  123
      },
     "b": {},
     "a": {}
}

EDIT: of course you wouldn't add field_order manually, but use some kind of adapter/wrapper.

@farcaller
Copy link
Author

farcaller commented Apr 12, 2018

I hacked this thing together that turns a list of k8s objects into a map by their name and then turnes them back into a list preserving the order:

I was thinking about a different thing, was a while since I checked on this ticket. Still, this solution solves at least some problems with ordering.

{
  named(objectlist)::
    {
      [k.kind + '/' +
       (if std.objectHas(k.metadata, 'namespace') then k.metadata.namespace + '/' else '') +
       k.metadata.name]: k,
      for k in
      std.makeArray(
          std.length(objectlist),
          function(i)
              objectlist[i] + {_named_object_index:: i})
    },

  list(objecthash)::
    local objs = [objecthash[f] for f in std.objectFields(objecthash)];
    local objsKeyed = {[std.toString(o._named_object_index)]: o for o in objs};
    std.makeArray(
        std.length(objs),
        function(i) objsKeyed[std.toString(i)])
}

It works nice in case when I use jsonnet to monkeypatch a bunch of objects but not as good if I need to add new objects to the map.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants