'JmesPath join or concatenate nested array elements

I realize there are several other JmesPath join questions here, but I'm having trouble with a separate problem that I haven't found any examples for, where I need to concatenate (ie, join) a set of JSON values that have dynamically-named keys into a single element.

If I start with the following JSON data structure:

{
  "data": [
  {
    "secmeetingdays":
    {
      "dayset_01":
      {
        "day_01": "M",
        "day_02": "W",
        "day_03": "F"
      },
      "dayset_02":
      {
        "day_01": "T",
        "day_02": "TH"
      }
    },
  }]
}

I would like to end up with something like this:

[
  [ 
    "M,W,F"
  ],
  [
    "T,TH"
  ]
]

I've started the query to flatten the data down, but am completely stuck with the join syntax. Nothing I try seems to be working.

  1. Attempt 1: data[].secmeetingdays | [0].*.*
[
  [
    "M",
    "W",
    "F"
  ],
  [
    "T",
    "TH"
  ]
]

Almost, but not quite there.

  1. Attempt 2: data[].secmeetingdays | [0].*.* | {join(',',@)}

fails

  1. Attempt 3: data[].secmeetingdays | [0].*.*.join(',',@)

fails

  1. Attempt 4: data[].secmeetingdays | {join(',',@[0].*.*)}

fails

  1. I tried avoiding 2 flattens to have some reference to grab onto inside the join.

Attempt 4 data[].secmeetingdays | [0].* | join(',',@[]).

fails

  1. Attempt 6 data[].secmeetingdays | [0].*.* | @.join(',',[]) Gives a result, but it's not what I want:
"M,W,F,T,TH"

Update:

  1. Attempt 7 data[].secmeetingdays[].*.* | [].join(',',@) gets me a lot closer but is also not exactly what I need:
[
  "M,W,F",
  "T,TH"
]

I might be able to work with this solution, but will leave this open in case someone has the accurate answer to the question.

The example here https://jmespath.org/ has a join, but it is only on a single list of items. How can I join the sub-arrays without affecting the structure of the parents?



Solution 1:[1]

data[*].secmeetingdays.values(@)[].values(@).join(',', @).to_array(@)

Gives you the example desired output but I see no benefit to wrapping each single string in an extra array.


data[].secmeetingdays.values(@) | [*][*].values(@).join(',', @)

Produces more logical output (to me) because it gives an array of daysets for each item in the data array:

[
  [
    "M,W,F",
    "T,TH"
  ]
]

Note that the proper way to deal with such data is to write a script that iterates the objects, parses the keys and guarantees ordered output after sorting the items. JSON parsers have no obligation to keep object properties ordered the same as they were stored/read, so blindly converting to an array as above is not certain to be the order you desire. Using key names to store order is superfluous. Chronologically ordered data should be stored as arrays like so:

{
  "data": [
    {
      "secmeetingdays": [
        [
          "M",
          "W",
          "F"
        ],
        [
          "T",
          "TH"
        ]
      ]
    }
  ]
}

Solution 2:[2]

 [[0].title,[1].title].join(',', @).to_array(@)
 RESULT: ["some1,some2"]

 [[0].title,[1].title].join(',', @)
 RESULT: "some1,some2"

 [[0].title,[1].title]
 RESULT: ["some1,some2"]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Walf
Solution 2 Vitalij