Remove all null values












3














I am trying to remove null values from a json object using jq. I found this issue on their github and so now I'm trying to remove them with del.
I have this:



'{ id: $customerId, name, phones: ([{ original: .phone }, 
{ original: .otherPhone}]), email} | del(. | nulls)'


This doesn't seem to do anything. However if I replace nulls with .phones it does remove the phone numbers.










share|improve this question




















  • 1




    Please extend this to be complete enough to run, showing input, actual output, and desired output. (For instance, you could provide minimal JSON input in a heredoc, by running jq '...your code here...' <<'EOF', including some JSON that demonstrates the problem, and having an EOF afterwards). See also the Help Center documentation on Minimal, Complete, Verifiable Examples.
    – Charles Duffy
    Sep 14 '16 at 22:31












  • ...as it is, it's hard to tell where in your data structure the NULs actually are, which is critical to being able to build or test a solution.
    – Charles Duffy
    Sep 14 '16 at 22:35










  • Note that while I'm voting to close the question as it's currently written, (1) it won't actually be closed unless others agree, and (2) editing a closed question automatically puts it into a queue to be considered for reopening, so extending it to include a MCVE should result in that closure being reversed.
    – Charles Duffy
    Sep 14 '16 at 22:37












  • @CharlesDuffy - Regarding your comment about "NULs" -- (1) the OP was asking about JSON "null", not "NUL"; (2) to anyone who knows jq, it's clear where the nulls are; (3) to anyone who knows JSON, it's fairly obvious.
    – peak
    Dec 15 '16 at 18:58












  • @peak, it's not obvious to me without following the github link to see the data at hand, and questions that only make sense when given out-of-band content are explicitly incomplete here -- that's extremely well-settled on meta, hence, my request for actual input to be included in the question itself. Yes, one could also edit the input data into the question itself -- either of us does that and there's no more grounds for disagreement. That said, asking the OP to do so themselves has the benefit of making it less likely they'll make the same mistake again in the future.
    – Charles Duffy
    Dec 15 '16 at 20:53


















3














I am trying to remove null values from a json object using jq. I found this issue on their github and so now I'm trying to remove them with del.
I have this:



'{ id: $customerId, name, phones: ([{ original: .phone }, 
{ original: .otherPhone}]), email} | del(. | nulls)'


This doesn't seem to do anything. However if I replace nulls with .phones it does remove the phone numbers.










share|improve this question




















  • 1




    Please extend this to be complete enough to run, showing input, actual output, and desired output. (For instance, you could provide minimal JSON input in a heredoc, by running jq '...your code here...' <<'EOF', including some JSON that demonstrates the problem, and having an EOF afterwards). See also the Help Center documentation on Minimal, Complete, Verifiable Examples.
    – Charles Duffy
    Sep 14 '16 at 22:31












  • ...as it is, it's hard to tell where in your data structure the NULs actually are, which is critical to being able to build or test a solution.
    – Charles Duffy
    Sep 14 '16 at 22:35










  • Note that while I'm voting to close the question as it's currently written, (1) it won't actually be closed unless others agree, and (2) editing a closed question automatically puts it into a queue to be considered for reopening, so extending it to include a MCVE should result in that closure being reversed.
    – Charles Duffy
    Sep 14 '16 at 22:37












  • @CharlesDuffy - Regarding your comment about "NULs" -- (1) the OP was asking about JSON "null", not "NUL"; (2) to anyone who knows jq, it's clear where the nulls are; (3) to anyone who knows JSON, it's fairly obvious.
    – peak
    Dec 15 '16 at 18:58












  • @peak, it's not obvious to me without following the github link to see the data at hand, and questions that only make sense when given out-of-band content are explicitly incomplete here -- that's extremely well-settled on meta, hence, my request for actual input to be included in the question itself. Yes, one could also edit the input data into the question itself -- either of us does that and there's no more grounds for disagreement. That said, asking the OP to do so themselves has the benefit of making it less likely they'll make the same mistake again in the future.
    – Charles Duffy
    Dec 15 '16 at 20:53
















3












3








3


2





I am trying to remove null values from a json object using jq. I found this issue on their github and so now I'm trying to remove them with del.
I have this:



'{ id: $customerId, name, phones: ([{ original: .phone }, 
{ original: .otherPhone}]), email} | del(. | nulls)'


This doesn't seem to do anything. However if I replace nulls with .phones it does remove the phone numbers.










share|improve this question















I am trying to remove null values from a json object using jq. I found this issue on their github and so now I'm trying to remove them with del.
I have this:



'{ id: $customerId, name, phones: ([{ original: .phone }, 
{ original: .otherPhone}]), email} | del(. | nulls)'


This doesn't seem to do anything. However if I replace nulls with .phones it does remove the phone numbers.







json bash null jq






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 16 '16 at 6:49









peak

30k83956




30k83956










asked Sep 14 '16 at 22:29









Ela

1,27131527




1,27131527








  • 1




    Please extend this to be complete enough to run, showing input, actual output, and desired output. (For instance, you could provide minimal JSON input in a heredoc, by running jq '...your code here...' <<'EOF', including some JSON that demonstrates the problem, and having an EOF afterwards). See also the Help Center documentation on Minimal, Complete, Verifiable Examples.
    – Charles Duffy
    Sep 14 '16 at 22:31












  • ...as it is, it's hard to tell where in your data structure the NULs actually are, which is critical to being able to build or test a solution.
    – Charles Duffy
    Sep 14 '16 at 22:35










  • Note that while I'm voting to close the question as it's currently written, (1) it won't actually be closed unless others agree, and (2) editing a closed question automatically puts it into a queue to be considered for reopening, so extending it to include a MCVE should result in that closure being reversed.
    – Charles Duffy
    Sep 14 '16 at 22:37












  • @CharlesDuffy - Regarding your comment about "NULs" -- (1) the OP was asking about JSON "null", not "NUL"; (2) to anyone who knows jq, it's clear where the nulls are; (3) to anyone who knows JSON, it's fairly obvious.
    – peak
    Dec 15 '16 at 18:58












  • @peak, it's not obvious to me without following the github link to see the data at hand, and questions that only make sense when given out-of-band content are explicitly incomplete here -- that's extremely well-settled on meta, hence, my request for actual input to be included in the question itself. Yes, one could also edit the input data into the question itself -- either of us does that and there's no more grounds for disagreement. That said, asking the OP to do so themselves has the benefit of making it less likely they'll make the same mistake again in the future.
    – Charles Duffy
    Dec 15 '16 at 20:53
















  • 1




    Please extend this to be complete enough to run, showing input, actual output, and desired output. (For instance, you could provide minimal JSON input in a heredoc, by running jq '...your code here...' <<'EOF', including some JSON that demonstrates the problem, and having an EOF afterwards). See also the Help Center documentation on Minimal, Complete, Verifiable Examples.
    – Charles Duffy
    Sep 14 '16 at 22:31












  • ...as it is, it's hard to tell where in your data structure the NULs actually are, which is critical to being able to build or test a solution.
    – Charles Duffy
    Sep 14 '16 at 22:35










  • Note that while I'm voting to close the question as it's currently written, (1) it won't actually be closed unless others agree, and (2) editing a closed question automatically puts it into a queue to be considered for reopening, so extending it to include a MCVE should result in that closure being reversed.
    – Charles Duffy
    Sep 14 '16 at 22:37












  • @CharlesDuffy - Regarding your comment about "NULs" -- (1) the OP was asking about JSON "null", not "NUL"; (2) to anyone who knows jq, it's clear where the nulls are; (3) to anyone who knows JSON, it's fairly obvious.
    – peak
    Dec 15 '16 at 18:58












  • @peak, it's not obvious to me without following the github link to see the data at hand, and questions that only make sense when given out-of-band content are explicitly incomplete here -- that's extremely well-settled on meta, hence, my request for actual input to be included in the question itself. Yes, one could also edit the input data into the question itself -- either of us does that and there's no more grounds for disagreement. That said, asking the OP to do so themselves has the benefit of making it less likely they'll make the same mistake again in the future.
    – Charles Duffy
    Dec 15 '16 at 20:53










1




1




Please extend this to be complete enough to run, showing input, actual output, and desired output. (For instance, you could provide minimal JSON input in a heredoc, by running jq '...your code here...' <<'EOF', including some JSON that demonstrates the problem, and having an EOF afterwards). See also the Help Center documentation on Minimal, Complete, Verifiable Examples.
– Charles Duffy
Sep 14 '16 at 22:31






Please extend this to be complete enough to run, showing input, actual output, and desired output. (For instance, you could provide minimal JSON input in a heredoc, by running jq '...your code here...' <<'EOF', including some JSON that demonstrates the problem, and having an EOF afterwards). See also the Help Center documentation on Minimal, Complete, Verifiable Examples.
– Charles Duffy
Sep 14 '16 at 22:31














...as it is, it's hard to tell where in your data structure the NULs actually are, which is critical to being able to build or test a solution.
– Charles Duffy
Sep 14 '16 at 22:35




...as it is, it's hard to tell where in your data structure the NULs actually are, which is critical to being able to build or test a solution.
– Charles Duffy
Sep 14 '16 at 22:35












Note that while I'm voting to close the question as it's currently written, (1) it won't actually be closed unless others agree, and (2) editing a closed question automatically puts it into a queue to be considered for reopening, so extending it to include a MCVE should result in that closure being reversed.
– Charles Duffy
Sep 14 '16 at 22:37






Note that while I'm voting to close the question as it's currently written, (1) it won't actually be closed unless others agree, and (2) editing a closed question automatically puts it into a queue to be considered for reopening, so extending it to include a MCVE should result in that closure being reversed.
– Charles Duffy
Sep 14 '16 at 22:37














@CharlesDuffy - Regarding your comment about "NULs" -- (1) the OP was asking about JSON "null", not "NUL"; (2) to anyone who knows jq, it's clear where the nulls are; (3) to anyone who knows JSON, it's fairly obvious.
– peak
Dec 15 '16 at 18:58






@CharlesDuffy - Regarding your comment about "NULs" -- (1) the OP was asking about JSON "null", not "NUL"; (2) to anyone who knows jq, it's clear where the nulls are; (3) to anyone who knows JSON, it's fairly obvious.
– peak
Dec 15 '16 at 18:58














@peak, it's not obvious to me without following the github link to see the data at hand, and questions that only make sense when given out-of-band content are explicitly incomplete here -- that's extremely well-settled on meta, hence, my request for actual input to be included in the question itself. Yes, one could also edit the input data into the question itself -- either of us does that and there's no more grounds for disagreement. That said, asking the OP to do so themselves has the benefit of making it less likely they'll make the same mistake again in the future.
– Charles Duffy
Dec 15 '16 at 20:53






@peak, it's not obvious to me without following the github link to see the data at hand, and questions that only make sense when given out-of-band content are explicitly incomplete here -- that's extremely well-settled on meta, hence, my request for actual input to be included in the question itself. Yes, one could also edit the input data into the question itself -- either of us does that and there's no more grounds for disagreement. That said, asking the OP to do so themselves has the benefit of making it less likely they'll make the same mistake again in the future.
– Charles Duffy
Dec 15 '16 at 20:53














5 Answers
5






active

oldest

votes


















5














The following illustrates how to remove all the null-valued keys from a JSON object:



jq -n '{"a":1, "b": null, "c": null} | with_entries( select( .value != null ) )'
{
"a": 1
}


Alternatively, paths/0 can be used as follows:



. as $o | [paths | {(.) : ($o[.])} ] | add


By the way, del/1 can also be used to achieve the same result, e.g. using this filter:



reduce keys as $k (.; if .[$k] == null then del(.[$k]) else . end)


Or less obviously, but more succinctly:



del( .[ (keys - [paths]) ] )


And for the record, here are two ways to use delpaths/1:



jq -n '{"a":1, "b": null, "c": null, "d":2} as $o
| $o
| delpaths( [ keys | select( $o[.] == null ) ] | map( [.]) )'


$ jq -n '{"a":1, "b": null, "c": null, "d":2}
| [delpaths((keys - paths) | map([.])) ] | add'


In both these last two cases, the output is the same:
{
"a": 1,
"d": 2
}






share|improve this answer























  • What is meant by /1 in the references to functions like del/1? I've seen it in other answers here, too, but not in jq's documentation.
    – L S
    Aug 1 '17 at 13:24






  • 1




    It is the arity of the function. The most recent versions of jq have a builtin named builtins which emits an array of strings of the form FUNCTOR/ARITY
    – peak
    Aug 1 '17 at 13:49



















2














[WARNING: the definition of walk/1 given in this response is problematic, not least for the reason given in the first comment; note also that jq 1.6 defines walk/1 differently.]



I am adding the new answer to emphasize the extended version of the script by @jeff-mercado. My version of the script assumes the empty values are as follows:





  • null;


  • - empty arrays;


  • {} - empty objects.


Removing of empty arrays and objects was borrowed from here https://stackoverflow.com/a/26196653/3627676.



def walk(f):
. as $in |
if type == "object" then
reduce keys as $key
( {}; . + { ($key): ( $in[$key] | walk(f) ) } ) | f
elif type == "array" then
select(length > 0) | map( walk(f) ) | f
else
f
end;

walk(
if type == "object" then
with_entries(select( .value != null and .value != {} and .value != ))
elif type == "array" then
map(select( . != null and . != {} and .!= ))
else
.
end
)





share|improve this answer



















  • 1




    Adding select(length > 0) | to def walk(f) is a mistake. For some JSON, it removes non-empty arrays. For other JSON (e.g., nested objects, each including some nulls and empty structures), only {} was returned. However, the condition shown here works with the original definition of walk. I just noticed this problem, so I can't change the vote I gave yesterday.
    – L S
    Aug 4 '17 at 15:41





















2














That's not what del/1 was meant to be used for. Given an object as input, if you wanted to remove the .phones property, you'd do:



del(.phones)


In other words, the parameter to del is the path to the property you wish to remove.



If you wanted to use this, you would have to figure out all the paths to null values and pass it in to this. That would be more of a hassle though.





For an easier approach, you'll have to walk through the object tree to find null values. If found, remove the corresponding property (or otherwise filter it out). Using walk/1, your filter could be applied recursively to exclude the null values.



walk(
if type == "object" then
with_entries(select(.value != null))
elif type == "array" then
map(select(. != null))
else
.
end
)


So if you had this for input:



{
"foo": null,
"bar": "bar",
"biz": [1,2,3,4,null],
"baz": {
"a": 1,
"b": null,
"c": ["a","b","c","null",32,null]
}
}


This filter would yield:



{
"bar": "bar",
"baz": {
"a": 1,
"c": ["a","b","c","null",32]
},
"biz": [1,2,3,4]
}


walk/1 will be added in a future version of jq so you'll have to add it. You can grab the definition here.



# Apply f to composite entities recursively, and to atoms
def walk(f):
. as $in
| if type == "object" then
reduce keys_unsorted as $key
( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
elif type == "array" then map( walk(f) ) | f
else f
end;





share|improve this answer























  • Jeff - First, using walk, you can just write: walk( if type == "object" then with_entries( select(.value != null) ) elif type == "array" then map(select(. != null)) else . end). Second, walk/1 is already available in the development version.
    – peak
    Sep 15 '16 at 1:29










  • Ah, you're right, I didn't realize it went depth first. Thanks.
    – Jeff Mercado
    Sep 15 '16 at 2:38



















0














[WARNING: the response below has several problems, not least those arising from the fact that 0|length is 0.]



Elaborating on an earlier answer, in addition to removing properties with null values, it's often helpful to remove JSON properties with empty array or object values (i.e., or {}), too.




ℹ️ — jq's walk() function (walk/1) makes this easy. walk() will be
available in a future version of jq (> jq-1.5), but its
definition
can be added to current filters.




The condition to pass to walk() for removing nulls and empty structures is:



walk(
if type == "object" then with_entries(select(.value|length > 0))
elif type == "array" then map(select(length > 0))
else .
end
)


Given this JSON input:



{
"notNullA": "notNullA",
"nullA": null,
"objectA": {
"notNullB": "notNullB",
"nullB": null,
"objectB": {
"notNullC": "notNullC",
"nullC": null
},
"emptyObjectB": {},
"arrayB": [
"b"
],
"emptyBrrayB":
},
"emptyObjectA": {},
"arrayA": [
"a"
],
"emptyArrayA":
}


Using this function gives the result:



{
"notNullA": "notNullA",
"objectA": {
"notNullB": "notNullB",
"objectB": {
"notNullC": "notNullC"
},
"arrayB": [
"b"
]
},
"arrayA": [
"a"
]
}





share|improve this answer































    0














    Elsewhere on this page, some interest has been expressed in
    using jq to eliminate recursively occurrences of and {} as well as null.



    Although it is possible to use the built-in definition of walk/1 to do
    this, it is a bit tricky to do so correctly. Here therefore is a variant version
    of walk/1 which makes it trivial to do so:



    def traverse(f):
    if type == "object" then map_values(traverse(f)) | f
    elif type == "array" then map( traverse(f) ) | f
    else f
    end;


    In order to make it easy to modify the criterion for removing elements,
    we define:



    def isempty: .==null or ((type|(.=="array" or .=="object")) and length==0);


    The solution is now simply:



    traverse(select(isempty|not))





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f39500608%2fremove-all-null-values%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      5 Answers
      5






      active

      oldest

      votes








      5 Answers
      5






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      5














      The following illustrates how to remove all the null-valued keys from a JSON object:



      jq -n '{"a":1, "b": null, "c": null} | with_entries( select( .value != null ) )'
      {
      "a": 1
      }


      Alternatively, paths/0 can be used as follows:



      . as $o | [paths | {(.) : ($o[.])} ] | add


      By the way, del/1 can also be used to achieve the same result, e.g. using this filter:



      reduce keys as $k (.; if .[$k] == null then del(.[$k]) else . end)


      Or less obviously, but more succinctly:



      del( .[ (keys - [paths]) ] )


      And for the record, here are two ways to use delpaths/1:



      jq -n '{"a":1, "b": null, "c": null, "d":2} as $o
      | $o
      | delpaths( [ keys | select( $o[.] == null ) ] | map( [.]) )'


      $ jq -n '{"a":1, "b": null, "c": null, "d":2}
      | [delpaths((keys - paths) | map([.])) ] | add'


      In both these last two cases, the output is the same:
      {
      "a": 1,
      "d": 2
      }






      share|improve this answer























      • What is meant by /1 in the references to functions like del/1? I've seen it in other answers here, too, but not in jq's documentation.
        – L S
        Aug 1 '17 at 13:24






      • 1




        It is the arity of the function. The most recent versions of jq have a builtin named builtins which emits an array of strings of the form FUNCTOR/ARITY
        – peak
        Aug 1 '17 at 13:49
















      5














      The following illustrates how to remove all the null-valued keys from a JSON object:



      jq -n '{"a":1, "b": null, "c": null} | with_entries( select( .value != null ) )'
      {
      "a": 1
      }


      Alternatively, paths/0 can be used as follows:



      . as $o | [paths | {(.) : ($o[.])} ] | add


      By the way, del/1 can also be used to achieve the same result, e.g. using this filter:



      reduce keys as $k (.; if .[$k] == null then del(.[$k]) else . end)


      Or less obviously, but more succinctly:



      del( .[ (keys - [paths]) ] )


      And for the record, here are two ways to use delpaths/1:



      jq -n '{"a":1, "b": null, "c": null, "d":2} as $o
      | $o
      | delpaths( [ keys | select( $o[.] == null ) ] | map( [.]) )'


      $ jq -n '{"a":1, "b": null, "c": null, "d":2}
      | [delpaths((keys - paths) | map([.])) ] | add'


      In both these last two cases, the output is the same:
      {
      "a": 1,
      "d": 2
      }






      share|improve this answer























      • What is meant by /1 in the references to functions like del/1? I've seen it in other answers here, too, but not in jq's documentation.
        – L S
        Aug 1 '17 at 13:24






      • 1




        It is the arity of the function. The most recent versions of jq have a builtin named builtins which emits an array of strings of the form FUNCTOR/ARITY
        – peak
        Aug 1 '17 at 13:49














      5












      5








      5






      The following illustrates how to remove all the null-valued keys from a JSON object:



      jq -n '{"a":1, "b": null, "c": null} | with_entries( select( .value != null ) )'
      {
      "a": 1
      }


      Alternatively, paths/0 can be used as follows:



      . as $o | [paths | {(.) : ($o[.])} ] | add


      By the way, del/1 can also be used to achieve the same result, e.g. using this filter:



      reduce keys as $k (.; if .[$k] == null then del(.[$k]) else . end)


      Or less obviously, but more succinctly:



      del( .[ (keys - [paths]) ] )


      And for the record, here are two ways to use delpaths/1:



      jq -n '{"a":1, "b": null, "c": null, "d":2} as $o
      | $o
      | delpaths( [ keys | select( $o[.] == null ) ] | map( [.]) )'


      $ jq -n '{"a":1, "b": null, "c": null, "d":2}
      | [delpaths((keys - paths) | map([.])) ] | add'


      In both these last two cases, the output is the same:
      {
      "a": 1,
      "d": 2
      }






      share|improve this answer














      The following illustrates how to remove all the null-valued keys from a JSON object:



      jq -n '{"a":1, "b": null, "c": null} | with_entries( select( .value != null ) )'
      {
      "a": 1
      }


      Alternatively, paths/0 can be used as follows:



      . as $o | [paths | {(.) : ($o[.])} ] | add


      By the way, del/1 can also be used to achieve the same result, e.g. using this filter:



      reduce keys as $k (.; if .[$k] == null then del(.[$k]) else . end)


      Or less obviously, but more succinctly:



      del( .[ (keys - [paths]) ] )


      And for the record, here are two ways to use delpaths/1:



      jq -n '{"a":1, "b": null, "c": null, "d":2} as $o
      | $o
      | delpaths( [ keys | select( $o[.] == null ) ] | map( [.]) )'


      $ jq -n '{"a":1, "b": null, "c": null, "d":2}
      | [delpaths((keys - paths) | map([.])) ] | add'


      In both these last two cases, the output is the same:
      {
      "a": 1,
      "d": 2
      }







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Sep 17 '16 at 4:00

























      answered Sep 14 '16 at 23:14









      peak

      30k83956




      30k83956












      • What is meant by /1 in the references to functions like del/1? I've seen it in other answers here, too, but not in jq's documentation.
        – L S
        Aug 1 '17 at 13:24






      • 1




        It is the arity of the function. The most recent versions of jq have a builtin named builtins which emits an array of strings of the form FUNCTOR/ARITY
        – peak
        Aug 1 '17 at 13:49


















      • What is meant by /1 in the references to functions like del/1? I've seen it in other answers here, too, but not in jq's documentation.
        – L S
        Aug 1 '17 at 13:24






      • 1




        It is the arity of the function. The most recent versions of jq have a builtin named builtins which emits an array of strings of the form FUNCTOR/ARITY
        – peak
        Aug 1 '17 at 13:49
















      What is meant by /1 in the references to functions like del/1? I've seen it in other answers here, too, but not in jq's documentation.
      – L S
      Aug 1 '17 at 13:24




      What is meant by /1 in the references to functions like del/1? I've seen it in other answers here, too, but not in jq's documentation.
      – L S
      Aug 1 '17 at 13:24




      1




      1




      It is the arity of the function. The most recent versions of jq have a builtin named builtins which emits an array of strings of the form FUNCTOR/ARITY
      – peak
      Aug 1 '17 at 13:49




      It is the arity of the function. The most recent versions of jq have a builtin named builtins which emits an array of strings of the form FUNCTOR/ARITY
      – peak
      Aug 1 '17 at 13:49













      2














      [WARNING: the definition of walk/1 given in this response is problematic, not least for the reason given in the first comment; note also that jq 1.6 defines walk/1 differently.]



      I am adding the new answer to emphasize the extended version of the script by @jeff-mercado. My version of the script assumes the empty values are as follows:





      • null;


      • - empty arrays;


      • {} - empty objects.


      Removing of empty arrays and objects was borrowed from here https://stackoverflow.com/a/26196653/3627676.



      def walk(f):
      . as $in |
      if type == "object" then
      reduce keys as $key
      ( {}; . + { ($key): ( $in[$key] | walk(f) ) } ) | f
      elif type == "array" then
      select(length > 0) | map( walk(f) ) | f
      else
      f
      end;

      walk(
      if type == "object" then
      with_entries(select( .value != null and .value != {} and .value != ))
      elif type == "array" then
      map(select( . != null and . != {} and .!= ))
      else
      .
      end
      )





      share|improve this answer



















      • 1




        Adding select(length > 0) | to def walk(f) is a mistake. For some JSON, it removes non-empty arrays. For other JSON (e.g., nested objects, each including some nulls and empty structures), only {} was returned. However, the condition shown here works with the original definition of walk. I just noticed this problem, so I can't change the vote I gave yesterday.
        – L S
        Aug 4 '17 at 15:41


















      2














      [WARNING: the definition of walk/1 given in this response is problematic, not least for the reason given in the first comment; note also that jq 1.6 defines walk/1 differently.]



      I am adding the new answer to emphasize the extended version of the script by @jeff-mercado. My version of the script assumes the empty values are as follows:





      • null;


      • - empty arrays;


      • {} - empty objects.


      Removing of empty arrays and objects was borrowed from here https://stackoverflow.com/a/26196653/3627676.



      def walk(f):
      . as $in |
      if type == "object" then
      reduce keys as $key
      ( {}; . + { ($key): ( $in[$key] | walk(f) ) } ) | f
      elif type == "array" then
      select(length > 0) | map( walk(f) ) | f
      else
      f
      end;

      walk(
      if type == "object" then
      with_entries(select( .value != null and .value != {} and .value != ))
      elif type == "array" then
      map(select( . != null and . != {} and .!= ))
      else
      .
      end
      )





      share|improve this answer



















      • 1




        Adding select(length > 0) | to def walk(f) is a mistake. For some JSON, it removes non-empty arrays. For other JSON (e.g., nested objects, each including some nulls and empty structures), only {} was returned. However, the condition shown here works with the original definition of walk. I just noticed this problem, so I can't change the vote I gave yesterday.
        – L S
        Aug 4 '17 at 15:41
















      2












      2








      2






      [WARNING: the definition of walk/1 given in this response is problematic, not least for the reason given in the first comment; note also that jq 1.6 defines walk/1 differently.]



      I am adding the new answer to emphasize the extended version of the script by @jeff-mercado. My version of the script assumes the empty values are as follows:





      • null;


      • - empty arrays;


      • {} - empty objects.


      Removing of empty arrays and objects was borrowed from here https://stackoverflow.com/a/26196653/3627676.



      def walk(f):
      . as $in |
      if type == "object" then
      reduce keys as $key
      ( {}; . + { ($key): ( $in[$key] | walk(f) ) } ) | f
      elif type == "array" then
      select(length > 0) | map( walk(f) ) | f
      else
      f
      end;

      walk(
      if type == "object" then
      with_entries(select( .value != null and .value != {} and .value != ))
      elif type == "array" then
      map(select( . != null and . != {} and .!= ))
      else
      .
      end
      )





      share|improve this answer














      [WARNING: the definition of walk/1 given in this response is problematic, not least for the reason given in the first comment; note also that jq 1.6 defines walk/1 differently.]



      I am adding the new answer to emphasize the extended version of the script by @jeff-mercado. My version of the script assumes the empty values are as follows:





      • null;


      • - empty arrays;


      • {} - empty objects.


      Removing of empty arrays and objects was borrowed from here https://stackoverflow.com/a/26196653/3627676.



      def walk(f):
      . as $in |
      if type == "object" then
      reduce keys as $key
      ( {}; . + { ($key): ( $in[$key] | walk(f) ) } ) | f
      elif type == "array" then
      select(length > 0) | map( walk(f) ) | f
      else
      f
      end;

      walk(
      if type == "object" then
      with_entries(select( .value != null and .value != {} and .value != ))
      elif type == "array" then
      map(select( . != null and . != {} and .!= ))
      else
      .
      end
      )






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 19 at 23:48









      peak

      30k83956




      30k83956










      answered Dec 15 '16 at 18:53









      jsxt

      817717




      817717








      • 1




        Adding select(length > 0) | to def walk(f) is a mistake. For some JSON, it removes non-empty arrays. For other JSON (e.g., nested objects, each including some nulls and empty structures), only {} was returned. However, the condition shown here works with the original definition of walk. I just noticed this problem, so I can't change the vote I gave yesterday.
        – L S
        Aug 4 '17 at 15:41
















      • 1




        Adding select(length > 0) | to def walk(f) is a mistake. For some JSON, it removes non-empty arrays. For other JSON (e.g., nested objects, each including some nulls and empty structures), only {} was returned. However, the condition shown here works with the original definition of walk. I just noticed this problem, so I can't change the vote I gave yesterday.
        – L S
        Aug 4 '17 at 15:41










      1




      1




      Adding select(length > 0) | to def walk(f) is a mistake. For some JSON, it removes non-empty arrays. For other JSON (e.g., nested objects, each including some nulls and empty structures), only {} was returned. However, the condition shown here works with the original definition of walk. I just noticed this problem, so I can't change the vote I gave yesterday.
      – L S
      Aug 4 '17 at 15:41






      Adding select(length > 0) | to def walk(f) is a mistake. For some JSON, it removes non-empty arrays. For other JSON (e.g., nested objects, each including some nulls and empty structures), only {} was returned. However, the condition shown here works with the original definition of walk. I just noticed this problem, so I can't change the vote I gave yesterday.
      – L S
      Aug 4 '17 at 15:41













      2














      That's not what del/1 was meant to be used for. Given an object as input, if you wanted to remove the .phones property, you'd do:



      del(.phones)


      In other words, the parameter to del is the path to the property you wish to remove.



      If you wanted to use this, you would have to figure out all the paths to null values and pass it in to this. That would be more of a hassle though.





      For an easier approach, you'll have to walk through the object tree to find null values. If found, remove the corresponding property (or otherwise filter it out). Using walk/1, your filter could be applied recursively to exclude the null values.



      walk(
      if type == "object" then
      with_entries(select(.value != null))
      elif type == "array" then
      map(select(. != null))
      else
      .
      end
      )


      So if you had this for input:



      {
      "foo": null,
      "bar": "bar",
      "biz": [1,2,3,4,null],
      "baz": {
      "a": 1,
      "b": null,
      "c": ["a","b","c","null",32,null]
      }
      }


      This filter would yield:



      {
      "bar": "bar",
      "baz": {
      "a": 1,
      "c": ["a","b","c","null",32]
      },
      "biz": [1,2,3,4]
      }


      walk/1 will be added in a future version of jq so you'll have to add it. You can grab the definition here.



      # Apply f to composite entities recursively, and to atoms
      def walk(f):
      . as $in
      | if type == "object" then
      reduce keys_unsorted as $key
      ( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
      elif type == "array" then map( walk(f) ) | f
      else f
      end;





      share|improve this answer























      • Jeff - First, using walk, you can just write: walk( if type == "object" then with_entries( select(.value != null) ) elif type == "array" then map(select(. != null)) else . end). Second, walk/1 is already available in the development version.
        – peak
        Sep 15 '16 at 1:29










      • Ah, you're right, I didn't realize it went depth first. Thanks.
        – Jeff Mercado
        Sep 15 '16 at 2:38
















      2














      That's not what del/1 was meant to be used for. Given an object as input, if you wanted to remove the .phones property, you'd do:



      del(.phones)


      In other words, the parameter to del is the path to the property you wish to remove.



      If you wanted to use this, you would have to figure out all the paths to null values and pass it in to this. That would be more of a hassle though.





      For an easier approach, you'll have to walk through the object tree to find null values. If found, remove the corresponding property (or otherwise filter it out). Using walk/1, your filter could be applied recursively to exclude the null values.



      walk(
      if type == "object" then
      with_entries(select(.value != null))
      elif type == "array" then
      map(select(. != null))
      else
      .
      end
      )


      So if you had this for input:



      {
      "foo": null,
      "bar": "bar",
      "biz": [1,2,3,4,null],
      "baz": {
      "a": 1,
      "b": null,
      "c": ["a","b","c","null",32,null]
      }
      }


      This filter would yield:



      {
      "bar": "bar",
      "baz": {
      "a": 1,
      "c": ["a","b","c","null",32]
      },
      "biz": [1,2,3,4]
      }


      walk/1 will be added in a future version of jq so you'll have to add it. You can grab the definition here.



      # Apply f to composite entities recursively, and to atoms
      def walk(f):
      . as $in
      | if type == "object" then
      reduce keys_unsorted as $key
      ( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
      elif type == "array" then map( walk(f) ) | f
      else f
      end;





      share|improve this answer























      • Jeff - First, using walk, you can just write: walk( if type == "object" then with_entries( select(.value != null) ) elif type == "array" then map(select(. != null)) else . end). Second, walk/1 is already available in the development version.
        – peak
        Sep 15 '16 at 1:29










      • Ah, you're right, I didn't realize it went depth first. Thanks.
        – Jeff Mercado
        Sep 15 '16 at 2:38














      2












      2








      2






      That's not what del/1 was meant to be used for. Given an object as input, if you wanted to remove the .phones property, you'd do:



      del(.phones)


      In other words, the parameter to del is the path to the property you wish to remove.



      If you wanted to use this, you would have to figure out all the paths to null values and pass it in to this. That would be more of a hassle though.





      For an easier approach, you'll have to walk through the object tree to find null values. If found, remove the corresponding property (or otherwise filter it out). Using walk/1, your filter could be applied recursively to exclude the null values.



      walk(
      if type == "object" then
      with_entries(select(.value != null))
      elif type == "array" then
      map(select(. != null))
      else
      .
      end
      )


      So if you had this for input:



      {
      "foo": null,
      "bar": "bar",
      "biz": [1,2,3,4,null],
      "baz": {
      "a": 1,
      "b": null,
      "c": ["a","b","c","null",32,null]
      }
      }


      This filter would yield:



      {
      "bar": "bar",
      "baz": {
      "a": 1,
      "c": ["a","b","c","null",32]
      },
      "biz": [1,2,3,4]
      }


      walk/1 will be added in a future version of jq so you'll have to add it. You can grab the definition here.



      # Apply f to composite entities recursively, and to atoms
      def walk(f):
      . as $in
      | if type == "object" then
      reduce keys_unsorted as $key
      ( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
      elif type == "array" then map( walk(f) ) | f
      else f
      end;





      share|improve this answer














      That's not what del/1 was meant to be used for. Given an object as input, if you wanted to remove the .phones property, you'd do:



      del(.phones)


      In other words, the parameter to del is the path to the property you wish to remove.



      If you wanted to use this, you would have to figure out all the paths to null values and pass it in to this. That would be more of a hassle though.





      For an easier approach, you'll have to walk through the object tree to find null values. If found, remove the corresponding property (or otherwise filter it out). Using walk/1, your filter could be applied recursively to exclude the null values.



      walk(
      if type == "object" then
      with_entries(select(.value != null))
      elif type == "array" then
      map(select(. != null))
      else
      .
      end
      )


      So if you had this for input:



      {
      "foo": null,
      "bar": "bar",
      "biz": [1,2,3,4,null],
      "baz": {
      "a": 1,
      "b": null,
      "c": ["a","b","c","null",32,null]
      }
      }


      This filter would yield:



      {
      "bar": "bar",
      "baz": {
      "a": 1,
      "c": ["a","b","c","null",32]
      },
      "biz": [1,2,3,4]
      }


      walk/1 will be added in a future version of jq so you'll have to add it. You can grab the definition here.



      # Apply f to composite entities recursively, and to atoms
      def walk(f):
      . as $in
      | if type == "object" then
      reduce keys_unsorted as $key
      ( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
      elif type == "array" then map( walk(f) ) | f
      else f
      end;






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 19 at 23:52









      peak

      30k83956




      30k83956










      answered Sep 14 '16 at 23:29









      Jeff Mercado

      90.6k18183211




      90.6k18183211












      • Jeff - First, using walk, you can just write: walk( if type == "object" then with_entries( select(.value != null) ) elif type == "array" then map(select(. != null)) else . end). Second, walk/1 is already available in the development version.
        – peak
        Sep 15 '16 at 1:29










      • Ah, you're right, I didn't realize it went depth first. Thanks.
        – Jeff Mercado
        Sep 15 '16 at 2:38


















      • Jeff - First, using walk, you can just write: walk( if type == "object" then with_entries( select(.value != null) ) elif type == "array" then map(select(. != null)) else . end). Second, walk/1 is already available in the development version.
        – peak
        Sep 15 '16 at 1:29










      • Ah, you're right, I didn't realize it went depth first. Thanks.
        – Jeff Mercado
        Sep 15 '16 at 2:38
















      Jeff - First, using walk, you can just write: walk( if type == "object" then with_entries( select(.value != null) ) elif type == "array" then map(select(. != null)) else . end). Second, walk/1 is already available in the development version.
      – peak
      Sep 15 '16 at 1:29




      Jeff - First, using walk, you can just write: walk( if type == "object" then with_entries( select(.value != null) ) elif type == "array" then map(select(. != null)) else . end). Second, walk/1 is already available in the development version.
      – peak
      Sep 15 '16 at 1:29












      Ah, you're right, I didn't realize it went depth first. Thanks.
      – Jeff Mercado
      Sep 15 '16 at 2:38




      Ah, you're right, I didn't realize it went depth first. Thanks.
      – Jeff Mercado
      Sep 15 '16 at 2:38











      0














      [WARNING: the response below has several problems, not least those arising from the fact that 0|length is 0.]



      Elaborating on an earlier answer, in addition to removing properties with null values, it's often helpful to remove JSON properties with empty array or object values (i.e., or {}), too.




      ℹ️ — jq's walk() function (walk/1) makes this easy. walk() will be
      available in a future version of jq (> jq-1.5), but its
      definition
      can be added to current filters.




      The condition to pass to walk() for removing nulls and empty structures is:



      walk(
      if type == "object" then with_entries(select(.value|length > 0))
      elif type == "array" then map(select(length > 0))
      else .
      end
      )


      Given this JSON input:



      {
      "notNullA": "notNullA",
      "nullA": null,
      "objectA": {
      "notNullB": "notNullB",
      "nullB": null,
      "objectB": {
      "notNullC": "notNullC",
      "nullC": null
      },
      "emptyObjectB": {},
      "arrayB": [
      "b"
      ],
      "emptyBrrayB":
      },
      "emptyObjectA": {},
      "arrayA": [
      "a"
      ],
      "emptyArrayA":
      }


      Using this function gives the result:



      {
      "notNullA": "notNullA",
      "objectA": {
      "notNullB": "notNullB",
      "objectB": {
      "notNullC": "notNullC"
      },
      "arrayB": [
      "b"
      ]
      },
      "arrayA": [
      "a"
      ]
      }





      share|improve this answer




























        0














        [WARNING: the response below has several problems, not least those arising from the fact that 0|length is 0.]



        Elaborating on an earlier answer, in addition to removing properties with null values, it's often helpful to remove JSON properties with empty array or object values (i.e., or {}), too.




        ℹ️ — jq's walk() function (walk/1) makes this easy. walk() will be
        available in a future version of jq (> jq-1.5), but its
        definition
        can be added to current filters.




        The condition to pass to walk() for removing nulls and empty structures is:



        walk(
        if type == "object" then with_entries(select(.value|length > 0))
        elif type == "array" then map(select(length > 0))
        else .
        end
        )


        Given this JSON input:



        {
        "notNullA": "notNullA",
        "nullA": null,
        "objectA": {
        "notNullB": "notNullB",
        "nullB": null,
        "objectB": {
        "notNullC": "notNullC",
        "nullC": null
        },
        "emptyObjectB": {},
        "arrayB": [
        "b"
        ],
        "emptyBrrayB":
        },
        "emptyObjectA": {},
        "arrayA": [
        "a"
        ],
        "emptyArrayA":
        }


        Using this function gives the result:



        {
        "notNullA": "notNullA",
        "objectA": {
        "notNullB": "notNullB",
        "objectB": {
        "notNullC": "notNullC"
        },
        "arrayB": [
        "b"
        ]
        },
        "arrayA": [
        "a"
        ]
        }





        share|improve this answer


























          0












          0








          0






          [WARNING: the response below has several problems, not least those arising from the fact that 0|length is 0.]



          Elaborating on an earlier answer, in addition to removing properties with null values, it's often helpful to remove JSON properties with empty array or object values (i.e., or {}), too.




          ℹ️ — jq's walk() function (walk/1) makes this easy. walk() will be
          available in a future version of jq (> jq-1.5), but its
          definition
          can be added to current filters.




          The condition to pass to walk() for removing nulls and empty structures is:



          walk(
          if type == "object" then with_entries(select(.value|length > 0))
          elif type == "array" then map(select(length > 0))
          else .
          end
          )


          Given this JSON input:



          {
          "notNullA": "notNullA",
          "nullA": null,
          "objectA": {
          "notNullB": "notNullB",
          "nullB": null,
          "objectB": {
          "notNullC": "notNullC",
          "nullC": null
          },
          "emptyObjectB": {},
          "arrayB": [
          "b"
          ],
          "emptyBrrayB":
          },
          "emptyObjectA": {},
          "arrayA": [
          "a"
          ],
          "emptyArrayA":
          }


          Using this function gives the result:



          {
          "notNullA": "notNullA",
          "objectA": {
          "notNullB": "notNullB",
          "objectB": {
          "notNullC": "notNullC"
          },
          "arrayB": [
          "b"
          ]
          },
          "arrayA": [
          "a"
          ]
          }





          share|improve this answer














          [WARNING: the response below has several problems, not least those arising from the fact that 0|length is 0.]



          Elaborating on an earlier answer, in addition to removing properties with null values, it's often helpful to remove JSON properties with empty array or object values (i.e., or {}), too.




          ℹ️ — jq's walk() function (walk/1) makes this easy. walk() will be
          available in a future version of jq (> jq-1.5), but its
          definition
          can be added to current filters.




          The condition to pass to walk() for removing nulls and empty structures is:



          walk(
          if type == "object" then with_entries(select(.value|length > 0))
          elif type == "array" then map(select(length > 0))
          else .
          end
          )


          Given this JSON input:



          {
          "notNullA": "notNullA",
          "nullA": null,
          "objectA": {
          "notNullB": "notNullB",
          "nullB": null,
          "objectB": {
          "notNullC": "notNullC",
          "nullC": null
          },
          "emptyObjectB": {},
          "arrayB": [
          "b"
          ],
          "emptyBrrayB":
          },
          "emptyObjectA": {},
          "arrayA": [
          "a"
          ],
          "emptyArrayA":
          }


          Using this function gives the result:



          {
          "notNullA": "notNullA",
          "objectA": {
          "notNullB": "notNullB",
          "objectB": {
          "notNullC": "notNullC"
          },
          "arrayB": [
          "b"
          ]
          },
          "arrayA": [
          "a"
          ]
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 19 at 23:17









          peak

          30k83956




          30k83956










          answered Aug 4 '17 at 17:06









          L S

          1,90312138




          1,90312138























              0














              Elsewhere on this page, some interest has been expressed in
              using jq to eliminate recursively occurrences of and {} as well as null.



              Although it is possible to use the built-in definition of walk/1 to do
              this, it is a bit tricky to do so correctly. Here therefore is a variant version
              of walk/1 which makes it trivial to do so:



              def traverse(f):
              if type == "object" then map_values(traverse(f)) | f
              elif type == "array" then map( traverse(f) ) | f
              else f
              end;


              In order to make it easy to modify the criterion for removing elements,
              we define:



              def isempty: .==null or ((type|(.=="array" or .=="object")) and length==0);


              The solution is now simply:



              traverse(select(isempty|not))





              share|improve this answer




























                0














                Elsewhere on this page, some interest has been expressed in
                using jq to eliminate recursively occurrences of and {} as well as null.



                Although it is possible to use the built-in definition of walk/1 to do
                this, it is a bit tricky to do so correctly. Here therefore is a variant version
                of walk/1 which makes it trivial to do so:



                def traverse(f):
                if type == "object" then map_values(traverse(f)) | f
                elif type == "array" then map( traverse(f) ) | f
                else f
                end;


                In order to make it easy to modify the criterion for removing elements,
                we define:



                def isempty: .==null or ((type|(.=="array" or .=="object")) and length==0);


                The solution is now simply:



                traverse(select(isempty|not))





                share|improve this answer


























                  0












                  0








                  0






                  Elsewhere on this page, some interest has been expressed in
                  using jq to eliminate recursively occurrences of and {} as well as null.



                  Although it is possible to use the built-in definition of walk/1 to do
                  this, it is a bit tricky to do so correctly. Here therefore is a variant version
                  of walk/1 which makes it trivial to do so:



                  def traverse(f):
                  if type == "object" then map_values(traverse(f)) | f
                  elif type == "array" then map( traverse(f) ) | f
                  else f
                  end;


                  In order to make it easy to modify the criterion for removing elements,
                  we define:



                  def isempty: .==null or ((type|(.=="array" or .=="object")) and length==0);


                  The solution is now simply:



                  traverse(select(isempty|not))





                  share|improve this answer














                  Elsewhere on this page, some interest has been expressed in
                  using jq to eliminate recursively occurrences of and {} as well as null.



                  Although it is possible to use the built-in definition of walk/1 to do
                  this, it is a bit tricky to do so correctly. Here therefore is a variant version
                  of walk/1 which makes it trivial to do so:



                  def traverse(f):
                  if type == "object" then map_values(traverse(f)) | f
                  elif type == "array" then map( traverse(f) ) | f
                  else f
                  end;


                  In order to make it easy to modify the criterion for removing elements,
                  we define:



                  def isempty: .==null or ((type|(.=="array" or .=="object")) and length==0);


                  The solution is now simply:



                  traverse(select(isempty|not))






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 20 at 0:06

























                  answered Nov 19 at 23:42









                  peak

                  30k83956




                  30k83956






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f39500608%2fremove-all-null-values%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      If I really need a card on my start hand, how many mulligans make sense? [duplicate]

                      Alcedinidae

                      Can an atomic nucleus contain both particles and antiparticles? [duplicate]