I need to clean json data from nulls, empty arrays, empty hashes. Current solution:
#!/usr/bin/perl -CSDA # Removes empty arrays, empty objects, and nulls from json structure. use utf8; use Modern::Perl qw{2017}; use JSON; use Data::Dumper; sub tidyup_json { my ($r) = @_; if (ref $r eq "HASH") { for my $k (keys %$r) { tidyup_json($$r{$k}); delete $$r{$k} if (ref $$r{$k} eq "HASH" && ! %{$$r{$k}}) or (ref $$r{$k} eq "ARRAY" && ! @{$$r{$k}}) or ! defined $$r{$k}; } } elsif (ref $r eq "ARRAY") { tidyup_json($$r[$_]) for 0 .. @$r - 1; @$r = grep { not ( (ref $_ eq "HASH" && ! %$_) or (ref $_ eq "ARRAY" && ! @$_) or ! defined $_ ) } @$r; } # use "$_[0]", because "$_[0]" is an alias to real reference that +was passed to the function $_[0] = undef if (ref $r eq "HASH" && ! %$r) or (ref $r eq "ARRAY" && ! @$r); } my $json = JSON->new->allow_nonref->relaxed->decode(do { local $/; <ST +DIN>; }); tidyup_json($json); print JSON->new->pretty->allow_nonref->canonical->encode($json);
What's the problem? See the "$_[0]" at the end of function? This is an alias for passed reference of json data. If that json data is empty hash, then the data must become "undef". So I have to modify data outside of function -- using alias. Is there more elegant way to handle it?
Here are results:# echo '{"empty inner hash": {}, "empty inner array": [], "some undef" +: null }' | ./tidyup_json null # echo '{"empty inner hash": {}, "empty inner array": [1], "some undef +": null }' | ./tidyup_json { "empty inner array" : [ 1 ] } # echo '{"empty inner hash": {}, "empty inner array": [1], "some undef +": 7 }' | ./tidyup_json { "empty inner array" : [ 1 ], "some undef" : 7 } # echo '{ }' | ./tidyup_json ## !!! important to return null null
PS. Beware that "true" and "false" jsonish data are references to blessed hashes.
In reply to Tidy up json from nulls, empty arrays and hashes by leszekdubiel
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |