简体   繁体   中英

Javascript - Extract values from nested object

I'm fairly new to programming (2-3 months in) and I'm struggling to find a way to fix this :

My goal : I've created a nested object with fantasy locations. I want to access the pop value from each of the "locations" I've generated and make the sum to know the total population.

Where I'm stuck : I can find and add the pop from the main object and its direct children, but for children of children it seems it doesn't work.

Here's a sample nested tree with a Parent location (Id:1), one children (Id: 2), and two grandchildren of Id 2 (id: 3 and 4).

[{"value":{
  "name":"Bridgejade",
  "type":"metropolis",
  "pop":12058,
  "rulName":[1,"Guzasa Rocwel"],
  "rulTitle":["king","queen"],
  "Id":"1",
  "Parent":""
  },
  "children":[{
    "value":{
      "name":"Bluriver",
      "type":"town",
      "pop":2830,
      "rulName":[1,"Esasadryd Bravrose"],
      "rulTitle":["count","countess"],
      "Id":"2",
      "Parent":"1"
      },
      "children":[{
        "value":{
          "name":"Lightlanding",
          "type":"village",
          "pop":382,
          "rulName":[0,"Barta Kal Eriin"],
          "rulTitle":["baron","baroness"],
          "Id":"3",
          "Parent":"2"
          }
        },{
        "value":{
          "name":"Syldov",
          "type":"village",
          "pop":297,
          "rulName":[0,"Sinne Whitelel"],
          "rulTitle":["baron","baroness"],
          "Id":"4",
          "Parent":"2"
          }
        }]
      }]
    }]

I've created a function to calculate the total population. Here's what I have so far:

function findTotPop(x) {
  var totalPop = 0;
  var childrenPop = 0;
  totalPop += x[0].value.pop;
  if (x[0].children.length >= 1) {

  }
  for (var enfant = 0; enfant <= (x[0].children.length - 1); enfant++) {
    if (x[0].children[enfant].children.length >= 1) {
      alert(enfant + " à " + x[0].children[enfant].children.length + " pEnfant")
    }
    for (var pEnfant = 0; pEnfant < x[0].children[enfant].children.length; pEnfant++) {
      console.log(x[0].children[enfant].children[pEnfant].value.pop)
    }
    var childrenPop = childrenPop + x[0].children[enfant].value.pop
  };
  console.log(x[0].children[0].children.length)
  totalPop += childrenPop
  return "La population totale est de " + totalPop;
}

I keep getting this error : Uncaught TypeError: Cannot read property 'length' of undefined at findTotPop (genFunctions.js:164)

Any help would be appreciated!

Please add an if condition check to check if there are any children to be actually checked like shown below, the for loop needs to be inside the if condition so that it doesn't error out when there are no children. You can also chain the null checks as shown below.

if (x[0] && x[0].children && x[0].children.length >= 1) {

By doing so, if there are no children in that object, the above code would not cause an error but return false, if we chain and conditions like shown above, if all results are not falsy, only the last value will be returned.

 const data = [{ "value": { "name": "Bridgejade", "type": "metropolis", "pop": 12058, "rulName": [1, "Guzasa Rocwel"], "rulTitle": ["king", "queen"], "Id": "1", "Parent": "" }, "children": [{ "value": { "name": "Bluriver", "type": "town", "pop": 2830, "rulName": [1, "Esasadryd Bravrose"], "rulTitle": ["count", "countess"], "Id": "2", "Parent": "1" }, "children": [{ "value": { "name": "Lightlanding", "type": "village", "pop": 382, "rulName": [0, "Barta Kal Eriin"], "rulTitle": ["baron", "baroness"], "Id": "3", "Parent": "2" } }, { "value": { "name": "Syldov", "type": "village", "pop": 297, "rulName": [0, "Sinne Whitelel"], "rulTitle": ["baron", "baroness"], "Id": "4", "Parent": "2" } }] }] }]; console.log(findTotPop(data)); function findTotPop(x) { var totalPop = 0; var childrenPop = 0; totalPop += x[0].value.pop; if (x[0] && x[0].children && x[0].children.length >= 1) { for (var enfant = 0; enfant <= (x[0].children.length - 1); enfant++) { if (x[0].children && x[0].children[enfant] && x[0].children[enfant].children && x[0].children[enfant].children.length >= 1) { for (var pEnfant = 0; pEnfant < x[0].children[enfant].children.length; pEnfant++) { childrenPop = childrenPop + x[0].children[enfant].value.pop } } }; } totalPop += childrenPop return "La population totale est de " + totalPop; }

Thank you Naren! With your suggestion and a few tweaks I managed to get it working! Here's the code I finally came up with for the function findTotPop:

function findTotPop(a) {
  var totalPop = 0;
  var childrenPop = 0;
  totalPop += a[0].value.pop;
  if (a[0].children && a[0].children.length >= 1) {
    for (var i = 0; i <= (a[0].children.length - 1); i++) {
      childrenPop = childrenPop + a[0].children[i].value.pop
      if (a[0].children && a[0].children[i] && a[0].children[i].children && a[0].children[i].children.length >= 1) {
        for (var y = 0; y < a[0].children[i].children.length; y++) {
          childrenPop = childrenPop + a[0].children[i].children[y].value.pop
        }
      }
    };
  }
  totalPop += childrenPop
  return "The total population is " + totalPop;
}

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