2

How to replace a value in a list in jsonnet. The basic example like this does not seem to work:

local users = import "../data/users.json";

// replace dots in username
local users_new = [
  u + { replaced_username: std.strReplace(u.username, ".", "_") }
  for u in users
];

{
  data: {
    [user.replaced_username]: {
      username: user.username,
    } for user in users_new
  }
}

The error message is like this:

RUNTIME ERROR: Field does not exist: strReplace
    templates/users.jsonnet:5:32-45 object <anonymous>
    templates/users.jsonnet:11:17-38    thunk <b>
    std.jsonnet:148:27  thunk <vals>
    std.jsonnet:611:21-24
    std.jsonnet:611:12-25   thunk <a>
    std.jsonnet:611:12-36   function <anonymous>
    std.jsonnet:611:12-36   function <anonymous>
    std.jsonnet:148:13-28   function <anonymous>
    templates/users.jsonnet:11:10-38    object <anonymous>
    During manifestation

As I understand from the error message I can't use calculated values in keys or do I miss something here?

UPD: Turned out that std.strReplace function is not present in jsonnet version 0.9.5. Problem solved by copying that function into a template.

Anton Babenko
  • 6,586
  • 2
  • 36
  • 44
  • 1
    Could you tell me what version of jsonnet are you using? The `std.strReplace` function was added relatively recently and documentation on jsonnet.org tracks current master. Most likely explanation is that you are using a version of jsonnet which doesn't have this function yet. Otherwise the code looks like it should work. – sbarzowski Feb 28 '18 at 06:51
  • 1
    BTW `["%s" % user.replaced_username]` seems pointless, why not just use `[user.replace_username].` – sbarzowski Feb 28 '18 at 06:53
  • @sbarzowski I install it via homebrew, `jsonnet -v Jsonnet commandline interpreter v0.9.5`. – Anton Babenko Feb 28 '18 at 08:21
  • @sbarzowski Thanks! Your answers helped a lot. I could copy `std.strReplace` function from the source into the same template and it works well. I wonder if there is a way to see which functions are available? Looking forward to using next release with cleaner code. – Anton Babenko Feb 28 '18 at 08:35
  • 2
    > I wonder if there is a way to see which functions are available? Yes: `jsonnet -e "std.objectFieldsAll(std)"` BTW I think there are plans to add "available since version X" note for functions added after the next release. – sbarzowski Feb 28 '18 at 08:57

1 Answers1

2

In this particular case, because the string to replace has a single character, you could locally implement the function with:

local strReplace(str, a, b) = (
  assert std.length(a) == 1;
  std.join(b, std.split(str, a))
);

strReplace(strReplace("hello world", "o", "0"), "l", "1")

Above example gives below output:

$ jsonnet -version
Jsonnet commandline interpreter v0.9.5
$ jsonnet strReplace.jsonnet 
"he110 w0r1d"
jjo
  • 2,595
  • 1
  • 8
  • 16