for loop over function that yields JSON object containing multiple fields?

4,140 views
Skip to first unread message

Preston Podaril

unread,
Feb 21, 2017, 2:28:02 PM2/21/17
to Jsonnet
The subject might not be the best, I am not exactly sure the best description for what I need and am having problems with.

I am struggling to figure out what I need to do to work out an issue I am having. What I currently have is a function that returns a JSON object containing multiple fields.

For example:

  foo(x):: {
    [x + i]: {
        .....
    } for i in ["1", "2"]
  },

I then want to for loop over that and really just concatenate all of the output of that into one object.

  local items = ["a", "b", "c"],
  foo(item) for item in items,

But trying to execute this simply throws the error: "STATIC ERROR: ......: Object comprehension can only have one field."

The results I am expecting would be the equivalent of:

  foo("a") + foo("b") + foo("c")

However, I need a way to do this programmatically. Hopefully I am just missing something subtle (or obvious) that helps me accomplish what I am needing.

Thanks,
Preston

Dave Cunningham

unread,
Feb 21, 2017, 2:38:31 PM2/21/17
to Preston Podaril, Jsonnet
Sounds like you want std.join({}, [foo(x) for x in ['a', 'b', 'c']]) except currently that's not allowed as join is restricted to arrays and strings.  Here's a cut down version of std.join() you can put in your jsonnet file or in a util library or whatever:

local join_objects(objs) = 
    local aux(arr, i, running) =
        if i >= std.length(arr) then
            running
        else
            aux(arr, i + 1, running + arr[i]) tailstrict;
    aux(objs, 0, {});

{
  foo(x):: {
    [x + i]: {
        data: "x = %s and i = %s" % [x, i],
    } for i in ["1", "2"]
  },
    
  local items = ["a", "b", "c"],
  joined: join_objects([self.foo(item) for item in items]),



--
You received this message because you are subscribed to the Google Groups "Jsonnet" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jsonnet+unsubscribe@googlegroups.com.
To post to this group, send email to jso...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jsonnet/23375729-42ac-48fc-83aa-7566b829d6e2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dave Cunningham

unread,
Feb 21, 2017, 2:40:21 PM2/21/17
to Preston Podaril, Jsonnet
Taking a step back, you can also just do this :)

{
  local items = ["a", "b", "c"],
  joined: {
    [x + i]: {
      data: "x = %s and i = %s" % [x, i],
    } for i in ["1", "2"] for x in items
  }
}

Preston Podaril

unread,
Feb 21, 2017, 5:48:10 PM2/21/17
to Jsonnet, ppod...@gmail.com
Thanks, the first option you gave me is exactly what I was looking for.

The latter one I had already done actually, several times to create a bunch of different functions for creating these objects using different forms of iterations. However the functions are much more complex than the example, with 20+ available function parameters possible, and since I already had one that provided all of the functionality I needed, I was hoping to be able to reuse it, so it would be easier to maintain the code base later.

I had thought of creating an array of these objects, but I was getting stuck in trying to figure out how to convert that into a plain object (I was hoping the join function might do that also, but I looked at it and saw it was only useful for arrays and strings). The key I was missing was making use of a recursive function call to iterate through all of the items in the array.

Thanks for you quick help!!
To unsubscribe from this group and stop receiving emails from it, send an email to jsonnet+u...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages