2

I have a JSON input like that:

{
  "details": [
    {
      "file": [
        "xxx-abc"
      ],
      "filePushedAt": "2021-10-25T09:31:39+02:00"
    },
    {
      "file": [
        "xxx-dfg"
      ],
      "filePushedAt": "2021-11-08T16:24:05+01:00"
    },
    {
      "file": [
        "hij"
      ],
      "filePushedAt": "2022-01-26T15:24:17+01:00"
    },
    {
      "file": [
        "xxx-klm"
      ],
      "filePushedAt": "2022-01-27T15:24:18+01:00"
    },
    {
      "file": [
        "opr"
      ],
      "filePushedAt": "2021-11-28T09:31:39+02:00"
    }
  ]
}

Using JMESPath I need to get the latest file (latest filePushedAt) which consists xxx prefix in file array.

I am able to extract files names in order by using

sort_by(details,& filePushedAt)[*].file[*] 

but cannot complete the task. I'm wondering if it is even possible without jq?

Barbaros Özhan
  • 59,113
  • 10
  • 31
  • 55
Murakami
  • 3,474
  • 7
  • 35
  • 89

1 Answers1

3

In order to filter the file arrays nested in the details one, you need to filter at the details level.
You will need the starts_with function in order to filter all elements of the file arrays for the prefix xxx.

So, knowing all this, we have the query:

details[?file[?starts_with(@,`xxx`)]]

That gives us the filtered array:

[
  {
    "file": [
      "xxx-abc"
    ],
    "filePushedAt": "2021-10-25T09:31:39+02:00"
  },
  {
    "file": [
      "xxx-dfg"
    ],
    "filePushedAt": "2021-11-08T16:24:05+01:00"
  },
  {
    "file": [
      "xxx-klm"
    ],
    "filePushedAt": "2022-01-27T15:24:18+01:00"
  }
]

Now, to fulfil you requirement, you still need, a sort_by, a reverse, because sort_by does not have an option to sort ascending or descending, and to select the first item of the array, with [0].

So, now, given the query

reverse(sort_by(details[?file[?starts_with(@,`xxx`)]], &filePushedAt))[0]

You do have the object you were looking for:

{
  "file": [
    "xxx-klm"
  ],
  "filePushedAt": "2022-01-27T15:24:18+01:00"
}
β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83
  • That's great answer. Thank you. Is it easy to reverse this logic meaning find the one which does not start with `xxx`? – Murakami Feb 13 '23 at 14:42
  • 1
    Sure, the not is an exclamation mark, so: ```reverse(sort_by(details[?file[?!starts_with(@,`xxx`)]], & filePushedAt))[0]``` – β.εηοιτ.βε Feb 13 '23 at 14:54