How to create new obj on JSON array without a replacement old one

Viewed 80

i have a JSON file

js.json

{
  "id": "json",
  "description": "test",
  "packages": [
    {
      "Group": "group1",
      "Name": "name1",
      "Version": "1.0.0"
    },
    {
      "Group": "group2",
      "Name": "name2",
      "Version": "1.0.0"
    },
    {
      "Group": "group3",
      "Name": "name3",
      "Version": "1.0.0"
    },
    {
      "Group": "group5",
      "Name": "name5",
      "Version": "1.0.0"
    }
  ]
}

It has 4 elements in the .packages array. I want to add a fifth element "group4" to the array to get

{
  "id": "json",
  "description": "test",
  "packages": [
    {
      "Group": "group1",
      "Name": "name1",
      "Version": "1.0.0"
    },
    {
      "Group": "group2",
      "Name": "name2",
      "Version": "1.0.0"
    },
    {
      "Group": "group3",
      "Name": "name3",
      "Version": "1.0.0"
    },
    {
      "Group": "group4",
      "Name": "name4",
      "Version": "1.0.0"
    },
    {
      "Group": "group5",
      "Name": "name5",
      "Version": "1.0.0"
    }
  ]
}

if i'm use

jq '.packages[3] |= . + {"Group":"group4", "Name":"name4", "Version":"1.0.0"}' jq.json 
{
  "id": "json",
  "description": "test",
  "packages": [
    {
      "Group": "group1",
      "Name": "name1",
      "Version": "1.0.0"
    },
    {
      "Group": "group2",
      "Name": "name2",
      "Version": "1.0.0"
    },
    {
      "Group": "group3",
      "Name": "name3",
      "Version": "1.0.0"
    },
    {
      "Group": "group4",
      "Name": "name4",
      "Version": "1.0.0"
    }
  ]
}

And i'm lost group5 element. Is it possible to add an item without losing the previous one? I understand that I can save the output of lost indexes and insert them with the new index, but this seems wrong

3 Answers

Update |= the .packages field by redifining it as a new array consisting of the first three elements .[:3], the new one [{…}] and the the rest .[3:]. Technically, we are constructing an array by piecing three arrays together +.

jq '.packages |= .[:3] + [{Group: "group4", Name: "name4", Version: "1.0.0"}] + .[3:]'
{
  "id": "json",
  "description": "test",
  "packages": [
    {
      "Group": "group1",
      "Name": "name1",
      "Version": "1.0.0"
    },
    {
      "Group": "group2",
      "Name": "name2",
      "Version": "1.0.0"
    },
    {
      "Group": "group3",
      "Name": "name3",
      "Version": "1.0.0"
    },
    {
      "Group": "group4",
      "Name": "name4",
      "Version": "1.0.0"
    },
    {
      "Group": "group5",
      "Name": "name5",
      "Version": "1.0.0"
    }
  ]
}

Demo

You want .packages |= . + [ { ... } ], which appends an element (well, an entire array, really), to the packages array, and not .packages[3] |= { ... }, which adds/merges some keys into the object at .packages[3].

You desire to insert a record into an array such that it remains sorted. The best and easiest solution is simply to append the record than sort the array. This has the advantage that knowing the insert position isn't needed.

.packages |= (
   . + [ { "Group": "group4", "Name": "name4", "Version": "1.0.0" } ] |
   sort_by( .Group )
)
Related