Cecilia Chan
Cecilia Chan

Reputation: 739

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

Upvotes: 0

Views: 1389

Answers (3)

PeterMader
PeterMader

Reputation: 7285

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)

Upvotes: 2

prasanth
prasanth

Reputation: 22490

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)

Upvotes: 0

Flocke
Flocke

Reputation: 1025

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

Upvotes: 0

Related Questions