JSON3 filtering a JSON object

How can I do this?

using JSON3

json = """
{
    "type": "FeatureCollection",
    "features": [
        {"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-120.8519857235256,49.00031611973458],[-121.75971003002991,48.99730808709781],[-122.7578837336236,49.00208871039554],[-122.8181833316832,48.93908116962877],[-122.64733447051435,48.77455252737079],[-122.49084265650254,48.742055031919904],[-122.48868909942897,48.645368268594936],[-120.91049069069057,48.64090993450829],[-120.7518453196052,48.657507828879076],[-120.65493525129513,48.72411426583626],[-120.73318115830104,48.78212632383125],[-120.76763807147795,48.95396018820711],[-120.8519857235256,49.00031611973458]]]},"properties":null,"id":53073},
        {"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-106.1119643335642,48.99940296696984],[-107.17976971586958,48.99999383052349],[-107.20597132693119,48.91259973945144],[-107.19340891066878,48.50925479178079],[-107.30144569052555,48.48089334120547],[-107.26052810612798,48.304762287348495],[-107.3692827383426,48.305138291428094],[-107.4048164300563,48.21828134904117],[-107.41486636306624,47.69166077813121],[-107.24904246840234,47.66152673689493],[-106.87468246378234,47.684892704698456],[-106.56600594990581,47.8148289716335],[-106.41884621654609,47.95738823266931],[-106.40054098142085,48.0619173667973],[-106.22933319407306,48.026411838709635],[-105.84420540408527,48.01029737815547],[-105.84348755172742,48.218979642331846],[-105.80436459822447,48.21914078693739],[-105.80436459822447,48.56329194950575],[-106.02115601029588,48.56399024279642],[-106.0215149364748,48.82391649153504],[-106.15180513942501,48.82391649153504],[-106.1119643335642,48.99940296696984]]]},"properties":null,"id":30105}
    ]
}
"""

obj = JSON3.read(json)

new_features = [f for f in obj.features if f.id == 53073]

julia> obj.features = new_features
ERROR: type Object has no field features
Stacktrace:
 [1] setproperty!(x::JSON3.Object{Base.CodeUnits{UInt8, String}, Vector{UInt64}}, f::Symbol, v::Vector{JSON3.Object{Base.CodeUnits{UInt8, String}, SubArray{UInt64, 1, Vector{UInt64}, Tuple{UnitRange{Int64}}, true}}})
   @ Base .\Base.jl:34
 [2] top-level scope
   @ REPL[60]:1

I just need to filter the "features" vector of objects to retain only those with particular ids.

obj = JSON3.read(json, Dict)

new_features = [f for f in obj["features"] if f["id"] == 53073]

obj["features"] = new_features

Does that work?

2 Likes

Nope. The docs say " The JSON3.Object supports the AbstactDict interface, but is read-only (it represents a view into the JSON source input)" so I guess it can’t be done this way. I was able to do it with JSON.jl though:

using JSON
json = """
{
    "type": "FeatureCollection",
    "features": [
        {"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-120.8519857235256,49.00031611973458],[-121.75971003002991,48.99730808709781],[-122.7578837336236,49.00208871039554],[-122.8181833316832,48.93908116962877],[-122.64733447051435,48.77455252737079],[-122.49084265650254,48.742055031919904],[-122.48868909942897,48.645368268594936],[-120.91049069069057,48.64090993450829],[-120.7518453196052,48.657507828879076],[-120.65493525129513,48.72411426583626],[-120.73318115830104,48.78212632383125],[-120.76763807147795,48.95396018820711],[-120.8519857235256,49.00031611973458]]]},"properties":null,"id":53073},
        {"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-106.1119643335642,48.99940296696984],[-107.17976971586958,48.99999383052349],[-107.20597132693119,48.91259973945144],[-107.19340891066878,48.50925479178079],[-107.30144569052555,48.48089334120547],[-107.26052810612798,48.304762287348495],[-107.3692827383426,48.305138291428094],[-107.4048164300563,48.21828134904117],[-107.41486636306624,47.69166077813121],[-107.24904246840234,47.66152673689493],[-106.87468246378234,47.684892704698456],[-106.56600594990581,47.8148289716335],[-106.41884621654609,47.95738823266931],[-106.40054098142085,48.0619173667973],[-106.22933319407306,48.026411838709635],[-105.84420540408527,48.01029737815547],[-105.84348755172742,48.218979642331846],[-105.80436459822447,48.21914078693739],[-105.80436459822447,48.56329194950575],[-106.02115601029588,48.56399024279642],[-106.0215149364748,48.82391649153504],[-106.15180513942501,48.82391649153504],[-106.1119643335642,48.99940296696984]]]},"properties":null,"id":30105}
    ]
}
"""
obj = JSON.parse(json)
new_features = [f for f in obj["features"] if f["id"] == 53073]
obj["features"] = new_features

You missed the change on the first line!

obj = JSON3.read(json, Dict) # -> Dict
# instead of
obj = JSON3.read(json) # -> JSON3.Object
2 Likes

Oops! You are right, this works! :grin:

1 Like