Here is my problem, I receive these kind of json data and I don't know in advance the keys (unknownProperty#) but the different objects in this data array have the same keys. What I need to do is to calculate the number of each level of alert (these levels are fixed). Here is what my end result should look like
var result = { unknownProperty1: { unknown: 0, ok: 2, warning: 0, ko: 1 },
unknownProperty2: { unknown: 0, ok: 0, warning: 2, ko: 1 },
unknownProperty3: { unknown: 3, ok: 0, warning: 0, ko: 0 },
unknownProperty4: { unknown: 0, ok: 0, warning: 3, ko: 0 },
unknownProperty5: { unknown: 0, ok: 0, warning: 2, ko: 1 } }
My script is working but I would like to know if there is any way to optimize/clean it with map/reduce/filter javascript function
const data = [
{
unknownProperty1: { alert: "ok", unusedItem1: "something" },
unknownProperty2: { alert: "warning", unusedItem1: "something" },
unknownProperty3: { alert: "unknown", unusedItem1: "something" },
unknownProperty4: { alert: "warning", unusedItem1: "something" },
unknownProperty5: { alert: "ko", unusedItem1: "something" }
},
{
unknownProperty1: { alert: "ok", unusedItem1: "something" },
unknownProperty2: { alert: "warning", unusedItem1: "something" },
unknownProperty3: { alert: "unknown", unusedItem1: "something" },
unknownProperty4: { alert: "warning", unusedItem1: "something" },
unknownProperty5: { alert: "warning", unusedItem1: "something" }
},
{
unknownProperty1: { alert: "ko", unusedItem1: "something" },
unknownProperty2: { alert: "ko", unusedItem1: "something" },
unknownProperty3: { alert: "unknown", unusedItem1: "something" },
unknownProperty4: { alert: "warning", unusedItem1: "something" },
unknownProperty5: { alert: "warning", unusedItem1: "something" }
}
];
var result = new Object();
var dataKeys = data.map(function(element) {
return Object.keys(element);
});
dataKeys[0].map(function(element) {
result[element] = { unknown: 0, ok: 0, warning: 0, ko: 0 };
});
//At this point the result is like what we expect but no calculation has been made yet
//We then increment the right values
data.map(function(element) {
for (var prop in element) {
if (Object.prototype.hasOwnProperty.call(element, prop)) {
// element correspond to the current object
// prop corresponds to the name of the key, for example 'unknownProperty1'
switch (element[prop].alert) {
case "ok":
result[prop].ok++;
break;
case "warning":
result[prop].warning++;
break;
case "unknown":
result[prop].unknown++;
break;
case "ko":
result[prop].ko++;
break;
default:
break;
}
}
}
});
console.log(result);
-
\$\begingroup\$ Is there a reason to redact the unknown properties? \$\endgroup\$dfhwze– dfhwze2019年09月03日 08:43:30 +00:00Commented Sep 3, 2019 at 8:43
-
\$\begingroup\$ This is just to illustrate I don't know them when I receive them \$\endgroup\$Thomas Fournet– Thomas Fournet2019年09月03日 08:45:38 +00:00Commented Sep 3, 2019 at 8:45
-
1\$\begingroup\$ I first posted my question here stackoverflow.com/questions/57767830/… \$\endgroup\$Thomas Fournet– Thomas Fournet2019年09月03日 08:45:59 +00:00Commented Sep 3, 2019 at 8:45
1 Answer 1
Compact Code
If you're looking for more compact code, you can start by avoiding redundant function declarations:
var dataKeys = data.map(function(element) { return Object.keys(element); });
var dataKeys = data.map(Object.keys);
And a compact notation for an empty object.
var result = new Object();
var result = {};
Pivot Table
What you're doing is pivotting data from rows to columns. You are correct to mention reduce
as this method could help us out here. It's possible to leave out the switch case if we just loop through the entries and aggregate the results.
var pivotTable = data.reduce((result, item) => {
Object.entries(item).forEach(([key, val]) => {
if (result[key] === undefined) {
result[key] = { unknown: 0, ok: 0, warning: 0, ko: 0 };
}
result[key][val.alert]++;
});
return result;
}, {});
console.log(pivotTable);