Search code examples
jsonbashjqswap

Chaining JQ if: if A then B C else D end


I would like to swap two values in a JQ if statement.

Given the following JSON:

{
  "food": {
    "fruit": [
      {
        "type": "apple",
        "count": 0
      },
      {
        "type": "banana",
        "count": 1
      },
      {
        "type": "orange",
        "count": 0
      }
    ]
  }
}

I want to swap the counts of the two objects based on a condition to result in the following, using JQ.

{
  "food": {
    "fruit": [
      {
        "type": "apple",
        "count": 1
      },
      {
        "type": "banana",
        "count": 0
      },
      {
        "type": "orange",
        "count": 0
      }
    ]
  }
}

So far I can correct the first fruit from 0 to 1 with

jq '
  if .food.fruit[] | select(.type=="apple") | .count == 0
  then
    .food.fruit[] | select(.type=="apple") | .count = 1
  else
    empty
  end
'

but I can't get the correct operator to modify the second. Is something like the following possible, using JQ?

jq '
  if .food.fruit[] | select(.type=="apple") | .count == 0
  then
    .food.fruit[] | select(.type=="apple") | .count = 1 &
    .food.fruit[] | select(.type=="banana") | .count = 0
  else
    empty
  end
'

I can't pipe it as that would pipe the single fruit object to the next line, so I'm not sure which operator I'm supposed to use here - if such functionality is even supported. Any help is greatly appreciated!


Solution

  • .food.fruit |= (
       ( .[] | select( .type == "apple"  ) | .count ) as $count1 |
       ( .[] | select( .type == "banana" ) | .count ) as $count2 |
    
       ( .[] | select( .type == "apple"  ) | .count ) = $count2 |
       ( .[] | select( .type == "banana" ) | .count ) = $count1
    )
    

    jq play


    .food.fruit |= (
       ( .[] | select( .type == "apple"  ) | .count ) as $count1 |
       ( .[] | select( .type == "banana" ) | .count ) as $count2 |
    
       .[] |= (
          .count = (
             if .type == "apple" then
                $count2
             elif .type == "banana" then
                $count1
             else
                .count
             end
          )
       )
    )
    

    jq play