How to filter array of objects by element property values using jq?

后端 未结 4 582
鱼传尺愫
鱼传尺愫 2020-12-01 20:35

I like to filter json files using jq:

jq . some.json

Given the json containing an array of objects:

{
  \"theList\": [
             


        
相关标签:
4条回答
  • 2020-12-01 21:08

    You could use select within map.

    .theList | map(select(.id == (2, 4)))
    

    Or more compact:

    [ .theList[] | select(.id == (2, 4)) ]
    

    Though written that way is a little inefficient since the expression is duplicated for every value being compared. It'll be more efficient and possibly more readable written this way:

    [ .theList[] | select(any(2, 4; . == .id)) ]
    
    0 讨论(0)
  • 2020-12-01 21:12

    From the docs:

    jq '.[] | select(.id == "second")' 
    

    Input [{"id": "first", "val": 1}, {"id": "second", "val": 2}]

    Output {"id": "second", "val": 2}

    I think you can do something like this:

    jq '.theList[] | select(.id == 2 or .id == 4)' array.json
    
    0 讨论(0)
  • 2020-12-01 21:12

    Using select(.id == (2, 4)) here is generally inefficient (see below).

    If your jq has IN/1, then it can be used to achieve a more efficient solution:

    .theList[] | select( .id | IN(2,3))
    

    If your jq does not have IN/1, then you can define it as follows:

    def IN(s): first(select(s == .)) // false;
    

    Efficiency

    One way to see the inefficiency is to use debug. The following expression, for example, results in 10 calls to debug, whereas only 9 checks for equality are actually needed:

    .theList[] | select( (.id == (2,3)) | debug )
    
    ["DEBUG:",false]
    ["DEBUG:",false]
    ["DEBUG:",true]
    {
      "id": 2,
      "name": "Fritz"
    }
    ["DEBUG:",false]
    ["DEBUG:",false]
    ["DEBUG:",true]
    {
      "id": 3,
      "name": "Walter"
    }
    ["DEBUG:",false]
    ["DEBUG:",false]
    ["DEBUG:",false]
    ["DEBUG:",false]
    

    index/1

    In principle, using index/1 should be efficient, but as of this writing (October 2017), its implementation, though fast (it is written in C), is inefficient.

    0 讨论(0)
  • 2020-12-01 21:21

    Here is a solution using indices:

    .theList | [ .[map(.id)|indices(2,4)[]] ]
    
    0 讨论(0)
提交回复
热议问题