As an addition to T.J Crowder's suggestion: the same basic principle, only without relying on an ES5 function, nor requiring a shim. Note: This solution does differ from your "desired output" in one way: rather than having each category reference an array that has only 1 element (an object literal), I just assign it an object literal directly. Your desired format would require you to access the bounced referrals like so: obj.result.Referral[0].bounces
, whereas I think it makes more sense if it were obj.result.Referral.bounces
, without the array in between.
//suppose a is the raw JSON data
var b = {result:{}};//this will become be the object you want
for (var i=0;i<a.result.length;i++)
{
b.result[a.result[i].category] = (function(obj)
{
var p, res = {};
for (p in obj)
{
if (p !== 'category' && obj.hasOwnProperty(p))
{
res[p] = obj[p];
}
}
return res;
}(a.result[i]));
}
This loops through the array, referenced by a.result
, each time using the value of a.result[i].category
as a property name for an object that holds the other data.
The result is:
console.log(JSON.stringify(b));
{"result":
{"Negative Notification":
{"event":"bounce",
"result":16},
"Referral":
{"event":"open",
"result":10},
"Positive Notification":
{"event":"bounce","result":176}
}
}
But really: why not format the data before you send it, if you have access to the code that outputs this data, change that code to better suite your needs.
Edit:
In response to your comment, I think what you're actually after is this:
var b={result{}};
for (i=0;i<a.result.length;i++)
{
b.result[a.result[i].category] = b.result[a.result[i].category] || {};//use existing, or create new object
b.result[a.result[i].category][a.result[i].event] = a.result[i].result;//add property for event type, assign value
}
After this code has run, object b
looks like this:
{"result":
{"Negative Notification":
{"open":2,
"delivered":34,
"processed":34,
"bounce":16},
"Referral":
{"bounce":1,
"delivered":17,
"processed":18,
"open":10},
"Positive Notification":
{"open":42,
"processed":504,
"delivered":504,
"bounce":176}
}
}
That means that, instead of using b.result.Referral[0].bounce
, you can use b.result.Referral.bounce
. But even more importantly, there's no need for that result
property in the first place:
var result ={};
for (i=0;i<a.result.length;i++)
{
result[a.result[i].category] = result[a.result[i].category] || {};
result[a.result[i].category][a.result[i].event] = a.result[i].result;
}
console.log(result);
{"Negative Notification":
{"open":2,
"delivered":34,
"processed":34,
"bounce":16},
"Referral":
{"bounce":1,
"delivered":17,
"processed":18,
"open":10},
"Positive Notification":
{"open":42,
"processed":504,
"delivered":504,
"bounce":176}
}