Let’s say I have an object containing objects that have 30 key-value pairs
each:
const data = { "foo": { "3/16/21": 'buzz', "3/17/21": 'fizz', ... "4/13/21": 'lorem', "4/14/21": 'ipsum' }, "bar": { "3/16/21": 'sit', "3/17/21": 'amet', ... "4/13/21": 'dummy', "4/14/21": 'text' }, };
My goal is to rebuild this object into something like this:
myData = [ {date: "3/16/21", foo: 'buzz', bar : 'sit'} {date: "3/17/21", foo: 'fizz', bar : 'amet'} , ... {date: "4/13/21", foo: 'lorem', bar : 'dummy'} {date: "4/14/21", foo: 'ipsum', bar : 'text'} ];
The function below works like charm but I feel like there is a 10x better way to do it. I would love to see your suggestions on how I could improve it.
const processAPIdata = (data) => { if (data) { var myData = []; for (var key in data) { if (!data.hasOwnProperty(key)) continue; var obj = data[key]; for (var prop in obj) { if (!obj.hasOwnProperty(prop)) continue; if (myData.length < 30) { myData.push({ date: prop }); } let pos = myData.map(function (e) { return e.date; }).indexOf(prop); myData[pos][key] = obj[prop]; } } } return myData; };
Advertisement
Answer
I’d group into an object indexed by date. When iterating, create the object for that date if it doesn’t exist yet, with { date }
(where date
is the inner property being iterated over), and assign a new property from the outer key (for the new key) and the inner value (for the new value):
const data = { "foo": { "3/16/21": 'buzz', "3/17/21": 'fizz', "4/13/21": 'lorem', "4/14/21": 'ipsum' }, "bar": { "3/16/21": 'sit', "3/17/21": 'amet', "4/13/21": 'dummy', "4/14/21": 'text' }, }; const newDataByDate = {}; for (const [key, obj] of Object.entries(data)) { for (const [date, val] of Object.entries(obj)) { newDataByDate[date] ??= { date }; newDataByDate[date][key] = val; } } console.log(Object.values(newDataByDate));