Home > Software engineering >  JQ get objects from array that has a field ending in string
JQ get objects from array that has a field ending in string

Time:02-24

I am trying to do what I think should be a fairly simple filter but I keep running into errors. I have this JSON:

{
  "versions": [
    {
      "archived": true,
      "description": "Cod version 3.3/Sprint 8",
      "id": "11500",
      "name": "v 3.3",
      "projectId": 11500,
      "releaseDate": "2016-03-15",
      "released": true,
      "self": "https://xxxxxxx.atlassian.net/rest/api/2/version/11500",
      "startDate": "2016-02-17",
      "userReleaseDate": "14/Mar/16",
      "userStartDate": "16/Feb/16"
    },
    {
      "archived": true,
      "description": "Hot fix",
      "id": "12000",
      "name": "v3.3.1",
      "projectId": 11500,
      "releaseDate": "2016-03-15",
      "released": true,
      "self": "https://xxxxxxx.atlassian.net/rest/api/2/version/12000",
      "startDate": "2016-03-15",
      "userReleaseDate": "14/Mar/16",
      "userStartDate": "14/Mar/16"
    },
    {
      "archived": false,
      "id": "29704",
      "name": "Sync-diff v1.0.0",
      "projectId": 11500,
      "releaseDate": "2022-02-16",
      "released": true,
      "self": "https://xxxxxxx.atlassian.net/rest/api/2/version/29704",
      "startDate": "2022-02-06",
      "userReleaseDate": "15/Feb/22",
      "userStartDate": "05/Feb/22"
    }
  ]
}

I just want to return any userReleaseDate that ends with '22'

I can get the boolean result by:

jq '.versions[].userReleaseDate | endswith("22")' 

prints out false, false, true

But I am not sure how to retrieve the objects. I tried variations of this:

[.versions[] as $keys |  $keys select(endswith("22"))]

and each threw an error. Any help would be appreciated.

CodePudding user response:

Use select directly on the list of objects, extract and check the release date inside its argument:

jq '.versions[] | select(.userReleaseDate | endswith("22"))'

CodePudding user response:

This was so close:

jq '.versions[].userReleaseDate | endswith("22")'

Rather than outputting whether they end with 22 or not, you want to select the values which end with 22. Fixed:

jq '.versions[].userReleaseDate | select( endswith("22") )'

Now, your question asks for the dates that end with 22, but the title suggests you want the objects. For that, you'd want something a little different:

jq '.versions[] | select( .userReleaseDate | endswith("22") )'       # As a stream
jq '[ .versions[] | select( .userReleaseDate | endswith("22") ) ]'   # As an array
jq '.versions | map( select( .userReleaseDate | endswith("22") ) )'  # As an array

There are a number of issues with [ .versions[] as $keys | $keys select(endswith("22")) ].

  • The keys of array element aren't usually called keys but indexes. $indexes would be a better name.

  • Except .versions[] gets the values of the array elements, not the keys/indexes. $values would be a better name.

  • Except the variable only takes on a single value at a time. $value would be a better name.

  • $version would be an even better name.

  • There's a | missing between $keys and select(endswith("22")).

  • There's no mention of userReleaseDate anywhere.

  • The result is placed in an array (because of the [ ]). There's no need or desire for this.

You could use

.versions[] as $version | $version.userReleaseDate | select(endswith("22"))

or

.versions[].userReleaseDate as $date | $date | select(endswith("22"))

But these are just overly-complicated versions of

jq '.versions[].userReleaseDate | select( endswith("22") )'
  • Related