简体   繁体   中英

return Object.keys in a map got undefined

What's wrong with my loop below? I want to calculate the total_count and return [total, total] after some manipulation within a map, but I got undefined.

my raw data

const raw = [{
  "device_info": {
    "name": "cam1",
  },
  "age_range": {
    "0-10": {
      "age_range": "0-10",
      "total_count": 15,
      "male_count": 6,
      "female_count": 9
    },
    "11-20": {
      "age_range": "11-20",
      "total_count": 11,
      "male_count": 7,
      "female_count": 4
    },
    "21-30": {
      "age_range": "21-30",
      "total_count": 922,
      "male_count": 452,
      "female_count": 470
    }
  }
}, {
  "device_info": {
    "name": "cam2",
  },
  "age_range": {
    "0-10": {
      "age_range": "0-10",
      "total_count": 1,
      "male_count": 1,
      "female_count": 0
    },
    "11-20": {
      "age_range": "11-20",
      "total_count": 2,
      "male_count": 0,
      "female_count": 2
    },
    "21-30": {
      "age_range": "21-30",
      "total_count": 90,
      "male_count": 58,
      "female_count": 32
    }
  }
}]

Loop

const x = raw.map(obj => {
  return Object.keys(obj).forEach(key => {
    let total = 0
    if (key === 'age_range') {
      total = Object.keys(obj.age_range).reduce((acum, innerKey) => {
        return acum + obj.age_range[innerKey].total_count
      }, 0)
      console.log(total)
    }
  });
})

console.log('x', x)

https://jsfiddle.net/19m3f7fs/1

Array#forEach doesn't return anything, use Array#map and Object.values instead:

const x = raw.map(obj => {
  return Object.values(obj.age_range).reduce((acc, item) => acc + item.total_count, 0)
})

Working example:

 const raw = [{ "device_info": { "name": "cam1", }, "age_range": { "0-10": { "age_range": "0-10", "total_count": 15, "male_count": 6, "female_count": 9 }, "11-20": { "age_range": "11-20", "total_count": 11, "male_count": 7, "female_count": 4 }, "21-30": { "age_range": "21-30", "total_count": 922, "male_count": 452, "female_count": 470 } } }, { "device_info": { "name": "cam2", }, "age_range": { "0-10": { "age_range": "0-10", "total_count": 1, "male_count": 1, "female_count": 0 }, "11-20": { "age_range": "11-20", "total_count": 2, "male_count": 0, "female_count": 2 }, "21-30": { "age_range": "21-30", "total_count": 90, "male_count": 58, "female_count": 32 } } }] const x = raw.map(obj => Object.values(obj.age_range).reduce((acc, item) => acc + item.total_count, 0)) console.log(x) 

Your problem is, that the raw.map returns whatever comes from Object.key(obj).forEach(...)

But for each is just an "iterator" function. It actually doesnt return anything.

See: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

Change like this .define the total in first map varible and remove the return from forEach .ForEach not returning anything .And add the return satement only inside the first map.

 const raw = [{ "device_info": { "name": "cam1", }, "age_range": { "0-10": { "age_range": "0-10", "total_count": 15, "male_count": 6, "female_count": 9 }, "11-20": { "age_range": "11-20", "total_count": 11, "male_count": 7, "female_count": 4 }, "21-30": { "age_range": "21-30", "total_count": 922, "male_count": 452, "female_count": 470 } } }, { "device_info": { "name": "cam2", }, "age_range": { "0-10": { "age_range": "0-10", "total_count": 1, "male_count": 1, "female_count": 0 }, "11-20": { "age_range": "11-20", "total_count": 2, "male_count": 0, "female_count": 2 }, "21-30": { "age_range": "21-30", "total_count": 90, "male_count": 58, "female_count": 32 } } }] const x = raw.map(obj => { let total = 0 Object.keys(obj).forEach(key => { if (key === 'age_range') { total = Object.keys(obj.age_range).reduce((acum, innerKey) => { return acum + obj.age_range[innerKey].total_count }, 0) } }); return total }) console.log('x', x) 

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