title: jq - filter using list of object identifier-index stored in a variable
body: <p>I'm writing a reusable Bash script that allows me to query an API to get data about parliamentary members and store it in csv format. </p>
  
  <p>The json response of the API has a lot of keys (name, gender, birthdate, commission membership, vote...), and, depending on what I'd like to do, I do not always want to capture the same keys. So I would like to abstract this part of the code in order to be able to write:</p>
  
  <pre><code>mp_keys= a,b,c,d
  
  curl https://mp.com | jq '. | [$mp_keys] | @csv'
  </code></pre>
  
  <p>so that it is interpreted by jq as    </p>
  
  <pre><code>jq '. | [.a, .b, .c, .d] | @ csv' 
  </code></pre>
  
  <p>I don't have a set structure for the variable format, so it could be: </p>
  
  <ul>
  <li><code>mp_keys="a,b,c,d"</code> or</li>
  <li><code>mp_keys=".a, .b, .c, .d"</code> or </li>
  <li><code>mp_key1=a, mp_key2=b, mp_key3=c, mp_key4=d</code></li>
  </ul>
  
  <p>I know that in jq I can use the following structure:</p>
  
  <pre><code>jq --arg mp_key1 "${mp_key1}" --arg mp_key2 "${mp_key2}" --arg mp_key3 "${mp_key3}" --arg mp_key4 "${mp_key4}" '. 
  | [.[$mp_key1], .[$mp_key2], .[$mp_key3], .[$mp_key4]] 
  | @csv'
  </code></pre>
  
  <p>But it obviously becomes tedious very quickly. </p>
  
  <p>Lastly I could also build the jq command as a string then apply <code>eval</code> to it but I would prefer using a proper jq solution.</p>
  
  <h2>Edit</h2>
  
  <p>I will break down @peak's answer for future reference, as it's very useful to understand what's happening. His answer is reproduced below:</p>
  
  <pre><code>mp_keys="a,b,c,d"
  
  echo '{"a":1, "b":2, "c":3, "d": 4}' |
  jq -r --arg mpk "$mp_keys" '
  ($mpk|split(",")) as $mpkeys
  | [ .[ $mpkeys[] ] ]
  | @csv '
  </code></pre>
  
  <p>First, it's important to understand that jq will:</p>
  
  <ol>
  <li>evaluate the value of <code>$mpkeys</code> first, which implies doing the <code>split(",")</code> on <code>$mpk</code></li>
  <li>then pass the json sent through <code>echo</code>.</li>
  </ol>
  
  <p>So we can do the same to understand what's happening. The <code>( )</code> tells jq to process this section in priority, so we can start by replacing the parenthesis with its results. </p>
  
  <ol>
  <li>the string <code>"a,b,c,d"</code>, stored in <code>$mpk</code>, is split and stored into the array <code>["a","b","c","d"]</code> as described in the <a href="https://stedolan.github.io/jq/manual/#Builtinoperatorsandfunctions" rel="nofollow noreferrer">section on <code>split(str)</code>of jq's manual</a>.</li>
  <li>The array is subsequently stored into <code>$mpkeys</code> through <code>as</code>.</li>
  </ol>
  
  <p>Which means that an equivalent of the initial code can be written as:</p>
  
  <pre><code>echo '{"a":1, "b":2, "c":3, "d": 4}' |
  jq -r --arg mpk "$mp_keys" '
  ["a","b","c","d] as $mpkeys
  | [ .[ $mpkeys[] ] ]
  | @csv '
  </code></pre>
  
  <p>Of course now the --arg is useless, as <code>$mpk</code> was there to hold our initial string. So we can simplify further with:</p>
  
  <pre><code>echo '{"a":1, "b":2, "c":3, "d": 4}' |
  jq -r '["a","b","c","d] as $mpkeys
  | [ .[ $mpkeys[] ] ]
  | @csv '
  </code></pre>
  
  <p>Let's now break down <code>[ .[ $mpkeys[] ] ]</code>:</p>
  
  <ul>
  <li>because <code>$mpkeys</code> is an array, <code>$mpkeys[]</code> stands for the individual elements of the array, equivalent to <code>"a","b","c","d"</code>. Instead of a single element (an array), we now have 4 elements (strings), which will be transformed individually by the filters around them (the brackets)</li>
  <li><code>$mpkeys[]</code> is then wrapped into <code>.[]</code> which applies to each of the 4 elements, and is consequently equivalent to <code>.["a"]</code>, <code>.["b"]</code>, <code>.["c"]</code>, <code>.["d"]</code>. Each of those elements is a generic object index, which are equivalent to the object-identifier index form (<code>.a, .b, .c, .d</code>) as <a href="https://stedolan.github.io/jq/manual/#Basicfilters" rel="nofollow noreferrer">described in jq's manual</a>.</li>
  <li>the final outer <code>[ ]</code> simply wraps everything inside an array, which is necessary to pass the result to <code>@csv</code>. </li>
  </ul>
  
  <p>So the equivalent to the code above is:</p>
  
  <pre><code>echo '{"a":1, "b":2, "c":3, "d": 4}' |
  jq -r '["a","b","c","d] as $mpkeys
  | [ .["a"], .["b"], .["c"], .["d"] ]
  | @csv '
  </code></pre>
  
  <p>Here <code>$mpkeys</code> serves no purpose, so we actually have:</p>
  
  <pre><code> echo '{"a":1, "b":2, "c":3, "d": 4}' |
  jq -r ' [ .["a"], .["b"], .["c"], .["d"] ]
  | @csv '
  </code></pre>
  
  <p>There we are.</p>