Krang Krang - 7 months ago 11
Javascript Question

organizing objects by name

Take the array of objects below "toursByHotels" — I want to take this data and get the sum of tours for each object that has the same name (the hotel's name, ie. Marriott, etc).

Is there an easier way in d3 than having to create 5 new arrays with the same names, then sum the tours of those?



var toursByHotel = [
{
"name": "Marriott",
"month": 1,
"tours": 10
},
{
"name": "Marriott",
"month": 2,
"tours": 15
},
{
"name": "Marriott",
"month": 3,
"tours": 8
},
{
"name": "Marriott",
"month": 4,
"tours": 12
},
{
"name": "Marriott",
"month": 5,
"tours": 18
},
{
"name": "Marriott",
"month": 6,
"tours": 25
},
{
"name": "Marriott",
"month": 7,
"tours": 40
},
{
"name": "Marriott",
"month": 8,
"tours": 33
},
{
"name": "Marriott",
"month": 9,
"tours": 25
},
{
"name": "Marriott",
"month": 10,
"tours": 21
},
{
"name": "Marriott",
"month": 11,
"tours": 18
},
{
"name": "Marriott",
"month": 12,
"tours": 14
},
{
"name": "Springhill",
"month": 1,
"tours": 10
},
{
"name": "Springhill",
"month": 2,
"tours": 15
},
{
"name": "Springhill",
"month": 3,
"tours": 8
},
{
"name": "Springhill",
"month": 4,
"tours": 12
},
{
"name": "Springhill",
"month": 5,
"tours": 18
},
{
"name": "Springhill",
"month": 6,
"tours": 25
},
{
"name": "Springhill",
"month": 7,
"tours": 40
},
{
"name": "Springhill",
"month": 8,
"tours": 33
},
{
"name": "Springhill",
"month": 9,
"tours": 25
},
{
"name": "Springhill",
"month": 10,
"tours": 21
},
{
"name": "Springhill",
"month": 11,
"tours": 18
},
{
"name": "Springhill",
"month": 12,
"tours": 14
},
{
"name": "Residence",
"month": 1,
"tours": 10
},
{
"name": "Residence",
"month": 2,
"tours": 15
},
{
"name": "Residence",
"month": 3,
"tours": 8
},
{
"name": "Residence",
"month": 4,
"tours": 12
},
{
"name": "Residence",
"month": 5,
"tours": 18
},
{
"name": "Residence",
"month": 6,
"tours": 25
},
{
"name": "Residence",
"month": 7,
"tours": 40
},
{
"name": "Residence",
"month": 8,
"tours": 33
},
{
"name": "Residence",
"month": 9,
"tours": 25
},
{
"name": "Residence",
"month": 10,
"tours": 21
},
{
"name": "Residence",
"month": 11,
"tours": 18
},
{
"name": "Residence",
"month": 12,
"tours": 14
},
{
"name": "Courtyard",
"month": 1,
"tours": 10
},
{
"name": "Courtyard",
"month": 2,
"tours": 15
},
{
"name": "Courtyard",
"month": 3,
"tours": 8
},
{
"name": "Courtyard",
"month": 4,
"tours": 12
},
{
"name": "Courtyard",
"month": 5,
"tours": 18
},
{
"name": "Courtyard",
"month": 6,
"tours": 25
},
{
"name": "Courtyard",
"month": 7,
"tours": 40
},
{
"name": "Courtyard",
"month": 8,
"tours": 33
},
{
"name": "Courtyard",
"month": 9,
"tours": 25
},
{
"name": "Courtyard",
"month": 10,
"tours": 21
},
{
"name": "Courtyard",
"month": 11,
"tours": 18
},
{
"name": "Courtyard",
"month": 12,
"tours": 14
},
{
"name": "Renaissance",
"month": 1,
"tours": 10
},
{
"name": "Renaissance",
"month": 2,
"tours": 15
},
{
"name": "Renaissance",
"month": 3,
"tours": 8
},
{
"name": "Renaissance",
"month": 4,
"tours": 12
},
{
"name": "Renaissance",
"month": 5,
"tours": 18
},
{
"name": "Renaissance",
"month": 6,
"tours": 25
},
{
"name": "Renaissance",
"month": 7,
"tours": 40
},
{
"name": "Renaissance",
"month": 8,
"tours": 33
},
{
"name": "Renaissance",
"month": 9,
"tours": 25
},
{
"name": "Renaissance",
"month": 10,
"tours": 21
},
{
"name": "Renaissance",
"month": 11,
"tours": 18
},
{
"name": "Renaissance",
"month": 12,
"tours": 14
}
];




Answer

You can use reduce and return object where each key is hotel name and value is sum of tours. DEMO

data = data.reduce(function(obj, e) {
  obj[e.name] = (obj[e.name] || 0) + e.tours;
  return obj;
}, {});

console.log(data)

If you want to get sum and percentage for each hotel you can do it like this DEMO

var result = {}

var total = data.reduce((a, b) => {return a + b.tours }, 0);
data.forEach(function(e) {
  if(!this[e.name]) {
    this[e.name] = {sum: e.tours, percentage: 0}
    result[e.name] = this[e.name];
  }
  this[e.name].sum += e.tours;
  this[e.name].percentage = (this[e.name].sum / total)*100;
}, {});

console.log(result)