Callum
Callum

Reputation: 313

How to iterate an array of objects and group the property values by their key name?

I have an array of objects named data, like so:

data = [{"timeslot":"7pm-8pm","Monday":60,"Tuesday":55},
        {"timeslot":"8pm-9pm","Monday":70,"Tuesday":60},
        {"timeslot":"9pm-10pm","Monday":40,"Tuesday":37}]

I want to get from this array three new arrays, like so:

timeslot = ["7pm-8pm", "8pm-9pm", "9pm-10pm"]
monday   = [60, 70, 40]
tuesdat  = [55, 60, 37]

Effectively grouping the data values by the data property name to which they belong.

Here is my Javascript

var timeslot = [];
var monday = [];
var tuesday = [];

var result = {};

// Iterate the objects of the array
for(var i = 0, len = data.length; i < len; i++) {
    var obj = data[i];
    // Iterate the properties of the object
    Object.keys(obj).forEach(function(key) {
        // Push the value of each property to an array sharing the property's key name
        result[key.toLowerCase()] = [obj[key]];
    });
}

console.log(result.timeslot, result.monday, result.tuesday);

This returns

["9pm-10pm"] [40] [37]

These are the property values of data's third and final object. It appears that the code inside the forEach is replacing the previous element of the new array with the current element. The new arrays each contain only one element, instead of the desired three.

How can I fix this?

Upvotes: 2

Views: 2174

Answers (2)

Supradeep
Supradeep

Reputation: 3266

The issue with your code is that, while you are iterating over the keys array, you are replacing the previous value each time here

result[key.toLowerCase()] = [obj[key]];  // This is replacing the existing value

To add a new entry to an array, you can use Array.push() method as shown below :

result[key.toLowerCase()].push([obj[key]]);

var data = [{"timeslot":"7pm-8pm","Monday":60,"Tuesday":55},{"timeslot":"8pm-9pm","Monday":70,"Tuesday":60},{"timeslot":"9pm-10pm","Monday":40,"Tuesday":37}];

var result = {}; 

data.map(function (each) {
  Object.keys(each).map(function (key){
    result[key] = result[key] || [];
    result[key].push(each[key]);
  });

});

console.log(result);

Upvotes: 2

Nina Scholz
Nina Scholz

Reputation: 386654

Basicall you are overwiting the last result with a new array

result[key.toLowerCase()] = [obj[key]];
// ^^^^^^^^^^^^^^^^^^^^^^   ^        ^

But you need only one array for a key and the push the actual value, like

result[key] = result[key] || []; // create array, if not exist
result[key].push(o[k]);          // push value

Working code:

var data = [{ timeslot: "7pm-8pm", Monday: 60, Tuesday: 55 }, { timeslot: "8pm-9pm", Monday: 70, Tuesday: 60}, { timeslot: "9pm-10pm", Monday: 40, Tuesday: 37 }],
    result = {};

data.forEach(function (o) {
    Object.keys(o).forEach(function (k) {
        var key = k.toLowerCase();
        result[key] = result[key] || [];
        result[key].push(o[k]);
    });
});

console.log(result);

Upvotes: 2

Related Questions