I have an array of objects and want every object in the array to have the same keys.
var obj1 = {"type": "test", "info": "a lot", "value": 7}; var obj2 = {"value": 5}; var obj3 = {"context": "demo", "info": "very long", "value": 3}; var obj4 = {"info": "no way"}; var dataSet = [obj1,obj2,obj3,obj4];
My attempt is to create an array with all possible keys in the first step. Then loop through that keys array and update the objects if the key was not found.
keys.forEach(function(a,b){ dataSet.forEach(function(c,d){ //key not found if(a in c === false) { //add key to object dataSet[b][a] = false; } }); });
Howewer, it does not seem to work correctly. This is my output:
after logic: [ { "type": false, "info": "a lot", "value": 7 }, { "value": 5, "info": false }, { "context": "demo", "info": "very long", "value": false }, { "info": "no way", "context": false } ]
What am I missing there?
var obj1 = {"type": "test", "info": "a lot", "value": 7}; var obj2 = {"value": 5}; var obj3 = {"context": "demo", "info": "very long", "value": 3}; var obj4 = {"info": "no way"}; var dataSet = [obj1,obj2,obj3,obj4]; var keys = []; console.log("before logic: ", dataSet); //Step 1: Fill keys array dataSet.forEach(function(a,b){ Object.keys(a).forEach(function(c,d) { //add keys to array if not already exists if(!keys.includes(c)) { keys.push(c); } }); }); //Step2: loop through keys array and add key to object if not existing keys.forEach(function(a,b){ dataSet.forEach(function(c,d){ //key not found if(a in c === false) { //add key to object dataSet[b][a] = false; } }); }); console.log("after logic: ", dataSet);
EDIT:
It would be perfect if the keys are always sorted in the same order too.
Advertisement
Answer
You can just collect the keys in a Set
using flatMap()
, and then assign the missing ones using forEach()
:
const dataSet = [ {"type": "test", "info": "a lot", "value": 7}, {"value": 5}, {"context": "demo", "info": "very long", "value": 3}, {"info": "no way"} ]; const keys = new Set(dataSet.flatMap(Object.keys)); dataSet.forEach((v) => keys.forEach((k) => v[k] = k in v ? v[k] : false)); console.log(dataSet);
To address the additional request of having the keys in the same order, note that historically, JavaScript object properties were unordered, so relying on the order of object properties in JavaScript is almost never a good idea.
That being said, it’s hard to get a fixed order when modifying the existing objects, but doable if you create new objects:
const dataSet = [ {"type": "test", "info": "a lot", "value": 7}, {"value": 5}, {"context": "demo", "info": "very long", "value": 3}, {"info": "no way"} ]; const keys = [...new Set(dataSet.flatMap(Object.keys))]; const result = dataSet.map((v) => keys.reduce((a, k) => ({ ...a, [k]: k in v ? v[k] : false }), {})); console.log(result);