| | 29 | 1 | | _isnullish(v) = v === missing || v === nothing |
| | | 2 | | |
| | 14 | 3 | | function _all_null(d::AbstractDict) |
| | 28 | 4 | | for v in values(d) |
| | 29 | 5 | | _isnullish(v) || return false |
| | 11 | 6 | | end |
| | 3 | 7 | | return true |
| | | 8 | | end |
| | | 9 | | |
| | 63 | 10 | | function _prune_null_objects!(v) |
| | 63 | 11 | | if isa(v, AbstractDict) |
| | 12 | 12 | | for (k, child) in v |
| | 23 | 13 | | v[k] = _prune_null_objects!(child) |
| | 23 | 14 | | end |
| | 12 | 15 | | return v |
| | 71 | 16 | | elseif isa(v, AbstractVector) && !isempty(v) && all(x -> isa(x, AbstractDict), v) |
| | 22 | 17 | | filter!(d -> !_all_null(d), v) |
| | 8 | 18 | | for d in v |
| | 11 | 19 | | _prune_null_objects!(d) |
| | 11 | 20 | | end |
| | 8 | 21 | | return v |
| | 43 | 22 | | elseif isa(v, AbstractVector) |
| | 5 | 23 | | for i in eachindex(v) |
| | 6 | 24 | | v[i] = _prune_null_objects!(v[i]) |
| | 9 | 25 | | end |
| | 5 | 26 | | return v |
| | | 27 | | end |
| | 38 | 28 | | return v |
| | | 29 | | end |
| | | 30 | | |
| | | 31 | | """ |
| | | 32 | | omit_null_objects!(jws::JSONWorksheet) |
| | | 33 | | |
| | | 34 | | Walk every row and drop elements of object arrays whose every field is `missing` |
| | | 35 | | or `nothing`. Recurses into nested dicts and arrays. Mixed arrays (some elements |
| | | 36 | | dicts, some not) are left untouched. Returns `jws`. |
| | | 37 | | """ |
| | 5 | 38 | | function omit_null_objects!(jws::JSONWorksheet) |
| | 5 | 39 | | for row in jws.data |
| | 11 | 40 | | for p in keys(row) |
| | 23 | 41 | | row[p] = _prune_null_objects!(row[p]) |
| | 23 | 42 | | end |
| | 11 | 43 | | end |
| | 5 | 44 | | return jws |
| | | 45 | | end |