简体   繁体   中英

Pulling data out of nested JSON object when name of object is unknown

I'm fetching data out of a mapping API (which returns JSON) and luckily for me as a JSON noob, the object I've been wanting to manipulate in the past has been named with a shortcut.

However, today I want to get data from an object which is named with a randomly generated number, which I won't know the name of when I fetch it. So I effectively want to write:

An example of the JSON is below. The data I am trying to access is the name of the Scottish Parliament constituency. So I am looking for an object which contains [type_name] = "Scottish Parliament constituency". I then want to look for the key/value pair within for name (in this example, Glasgow Kelvin).

In this case, the object has the randomly generated name of 134955, but if I don't know that beforehand, how I can write the javascript to scope within the find if it has that type_name, and therefore pull the name out? The objects aren't always the name number and order, so I can't just do it by saying "get the first object".

{
    "wgs84_lat": 55.861509653107056,
    "coordsyst": "G",
    "shortcuts": {
        "WMC": 14425,
        "ward": 151284,
        "council": 2579
    },
    "wgs84_lon": -4.246702245398941,
    "postcode": "G1 1BX",
    "easting": 259485,
    "areas": {
        "134955": {
            "parent_area": 148764,
            "generation_high": 40,
            "all_names": {},
            "id": 134955,
            "codes": {
                "gss": "S16000117",
                "unit_id": "41386"
            },
            "name": "Glasgow Kelvin",
            "country": "S",
            "type_name": "Scottish Parliament constituency",
            "generation_low": 15,
            "country_name": "Scotland",
            "type": "SPC"
        },
        "2579": {
            "parent_area": null,
            "generation_high": 40,
            "all_names": {},
            "id": 2579,
            "codes": {
                "gss": "S12000049",
                "local-authority-canonical": "GLG",
                "unit_id": "30631"
            },
            "name": "Glasgow City Council",
            "country": "S",
            "type_name": "Unitary Authority",
            "generation_low": 36,
            "country_name": "Scotland",
            "type": "UTA"
        },
        "151284": {
            "parent_area": 2579,
            "generation_high": 40,
            "all_names": {},
            "id": 151284,
            "codes": {
                "gss": "S13002976",
                "unit_id": "43375"
            },
            "name": "Anderston/City/Yorkhill",
            "country": "S",
            "type_name": "Unitary Authority ward (UTW)",
            "generation_low": 31,
            "country_name": "Scotland",
            "type": "UTW"
        },
        "14425": {
            "parent_area": null,
            "generation_high": 40,
            "all_names": {},
            "id": 14425,
            "codes": {
                "gss": "S14000029",
                "unit_id": "33920"
            },
            "name": "Glasgow Central",
            "country": "S",
            "type_name": "UK Parliament constituency",
            "generation_low": 2,
            "country_name": "Scotland",
            "type": "WMC"
        }
    }
}

This should do it:

Object.values(data.areas)
  .filter(a=>a.type_name=="Scottish Parliament constituency")
  .map   (a=>a.name)

 const data={ "wgs84_lat": 55.861509653107056, "coordsyst": "G", "shortcuts": { "WMC": 14425, "ward": 151284, "council": 2579 }, "wgs84_lon": -4.246702245398941, "postcode": "G1 1BX", "easting": 259485, "areas": { "134955": { "parent_area": 148764, "generation_high": 40, "all_names": {}, "id": 134955, "codes": { "gss": "S16000117", "unit_id": "41386" }, "name": "Glasgow Kelvin", "country": "S", "type_name": "Scottish Parliament constituency", "generation_low": 15, "country_name": "Scotland", "type": "SPC" }, "2579": { "parent_area": null, "generation_high": 40, "all_names": {}, "id": 2579, "codes": { "gss": "S12000049", "local-authority-canonical": "GLG", "unit_id": "30631" }, "name": "Glasgow City Council", "country": "S", "type_name": "Unitary Authority", "generation_low": 36, "country_name": "Scotland", "type": "UTA" }, "151284": { "parent_area": 2579, "generation_high": 40, "all_names": {}, "id": 151284, "codes": { "gss": "S13002976", "unit_id": "43375" }, "name": "Anderston/City/Yorkhill", "country": "S", "type_name": "Unitary Authority ward (UTW)", "generation_low": 31, "country_name": "Scotland", "type": "UTW" }, "14425": { "parent_area": null, "generation_high": 40, "all_names": {}, "id": 14425, "codes": { "gss": "S14000029", "unit_id": "33920" }, "name": "Glasgow Central", "country": "S", "type_name": "UK Parliament constituency", "generation_low": 2, "country_name": "Scotland", "type": "WMC" } } }; console.log(Object.values(data.areas).filter(a=>a.type_name=="Scottish Parliament constituency").map(a=>a.name))

First you .filter() through all the Object.values() of data.areas for the a.type_name=="Scottish Parliament constituency" and then you apply a .map() to extract the name property from the filtered object(s).

In Addition to above comment , You can use "find" if you want to return once the first match occur!

const element = Object.keys(x.areas).find(item => x.areas[item].type_name === "Scottish Parliament constituency");

const obj = x.areas[element]; //Complete Object on matched type_name

I can suggest a recursive approach in order to get the object containing the value. After, you can use the object to get the desired value:

 var data = { "wgs84_lat": 55.861509653107056, "coordsyst": "G", "shortcuts": { "WMC": 14425, "ward": 151284, "council": 2579 }, "wgs84_lon": -4.246702245398941, "postcode": "G1 1BX", "easting": 259485, "areas": { "134955": { "parent_area": 148764, "generation_high": 40, "all_names": {}, "id": 134955, "codes": { "gss": "S16000117", "unit_id": "41386" }, "name": "Glasgow Kelvin", "country": "S", "type_name": "Scottish Parliament constituency", "generation_low": 15, "country_name": "Scotland", "type": "SPC" }, "2579": { "parent_area": null, "generation_high": 40, "all_names": {}, "id": 2579, "codes": { "gss": "S12000049", "local-authority-canonical": "GLG", "unit_id": "30631" }, "name": "Glasgow City Council", "country": "S", "type_name": "Unitary Authority", "generation_low": 36, "country_name": "Scotland", "type": "UTA" }, "151284": { "parent_area": 2579, "generation_high": 40, "all_names": {}, "id": 151284, "codes": { "gss": "S13002976", "unit_id": "43375" }, "name": "Anderston/City/Yorkhill", "country": "S", "type_name": "Unitary Authority ward (UTW)", "generation_low": 31, "country_name": "Scotland", "type": "UTW" }, "14425": { "parent_area": null, "generation_high": 40, "all_names": {}, "id": 14425, "codes": { "gss": "S14000029", "unit_id": "33920" }, "name": "Glasgow Central", "country": "S", "type_name": "UK Parliament constituency", "generation_low": 2, "country_name": "Scotland", "type": "WMC" } } }; function findEle(parent, data, val) { if (data == null) { return null; } if (typeof data == 'object') { var eles = Object.entries(data); for (var i = 0; i < eles.length; i++) { if (typeof eles[i][1] == 'object') { var result = findEle(eles[i], eles[i][1], val); if (result != null) { if (eles[i][1].hasOwnProperty('type_name')) { return eles[i][1]; } else { return result; } } } else { if (eles[i][1] == val) { return parent; } } } } return null; } var result = findEle(data, data, 'Scottish Parliament constituency'); console.log('Name is: ' + result.name); console.log('---------------'); console.log(result)
 .as-console-wrapper { max-height: 100%!important; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM