1

I am trying to sort this source data outeractivities by outer_name and, then, activities by and inner_name:

Sourcedata.json:

[
    {
        "outeractivities": [
            {
                "outer_name": "2"
            },
            {
                "outer_name": "1",
                "activities": [
                    {
                        "inner_name": "B"
                    },
                    {
                        "inner_name": "A"
                    }
                ]
            }
        ]
    }
]

Expected output:

[
    {
        "outeractivities": [
            {
                "activities": [
                    {
                        "inner_name": "A"
                    },
                    {
                        "inner_name": "B"
                    }
                ],
                "outer_name": "1"
            },
            {
                "outer_name": "2"
            }
        ]
    }
]

By using

cat Sourcedata.json | jp "[].{outeractivities:sort_by(outeractivities[]. \
{outer_name:outer_name, activities:sort_by(activities[].{inner_name:inner_name},&inner_name) \
},&outer_name)  \
}"

I will get the exception:

Error evaluating JMESPath expression: Invalid type for: <nil>, expected: []jmespath.jpType{"array"}

If I change

{
          "outer_name": "2"
}

to

{
          "outer_name": "2",
          "activities": []
}

It does work.
How can I fix this?

β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83
Wibbico
  • 15
  • 4

1 Answers1

2

Since the error is occurring due to the fact that sort_by is failing to process properly when the property to sort on does not exists, what you could do is to make a list of two lists:

  • one with all the outeractivities having the activities property, sorted on this field
  • one with all the outeractivities that does not have the activities property

And, then, flatten those two lists.

Given the query:

[].{ 
  outeractivities: sort_by(
    [
      outeractivities[?activities == null], 
      outeractivities[?activities != null].{ 
        outer_name: outer_name, 
        activities: sort_by(activities, &inner_name)
      }
    ] [], 
    &outer_name
  )
}

This yields the expected:

[
  {
    "outeractivities": [
      {
        "outer_name": "1",
        "activities": [
          {
            "inner_name": "A"
          },
          {
            "inner_name": "B"
          }
        ]
      },
      {
        "outer_name": "2"
      }
    ]
  }
]
β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83