Reputation: 116
I have this data from CSV:
Group Profession Status Count
6 Fisherman Offer Accepted 1
6 Fisherman All 1
7 Fisherman Offer Accepted 1
7 Fisherman All 1
8 Banker Onboard 2
8 Banker All 2
8 Cook Onboard 4
8 Cook All 4
8 Developer Onboard 2
8 Developer All 2
9 Banker Onboard 2
9 Banker Offer Accepted 1
9 Banker All 3
Which I need to return as a JSON array:
"Fisherman" : {
6 : {
"Offer Accepted" : 1,
"All" : 1
},
7 : {
"Offer Accepted" : 1,
"All" : 1
}
},
"Banker" : {
8 : {
"Onboard" : 2,
"All" : 2
},
9 : {
"Onboard" : 2,
"Offer Accepted" : 1,
"All" : 3
}
},
....so on
So far, what I did was I got all the unique Profession and Group.
Then I looped through all the data and compared if there's a match for Profession AND Group.
for(var d in data) {
var json = [];
for(var p in profession) {
for(var g in group) {
if(data[d]["Profession"] == profession[p] && data[d]["Group"] == group[g]) {
json.push({data[d]["Status"] : data[d]["Count"]});
// put 'json' variable in JSON array with key group?
}
}
}
}
If there is a match, I created an array wherein I pushed the Status and Count.
But I really don't know how to proceed from there.
Thank you for your help!
Upvotes: 1
Views: 77
Reputation: 386670
Suppose data is an array with objects like,
{ Group: 6, Profession: 'Fisherman', Status: 'Offer Accepted', Count: 1 }
then you could use the following
var order = ['Profession', 'Group', 'Status'],
object = {};
data.forEach(function (d) {
order.reduce(function (r, a) {
r[d[a]] = r[d[a]] || {};
return r[d[a]];
}, object).Count = d.Count;
});
How it works:
d
is an object with the structure like above.oder
is an array with keys in the wanted order for the resultobject
. (I renamedjson
toobject
, because JSON is a string with a special formatting and not an object, like here necessary.)For an assignment of count, it is necessary to know the path to the property. This is granted with iterating over the
order
for the keys of the actual objectd
.
r[d[a]] = r[d[a]] || {};
This d[a]
is taken for a check if the property exits and if not to assign an empty object.
At the end of the callback, the reference to the last object r[d[a]]
is returned.
At last, a new property Count
is assinged with the value of d.Count
object a d[a] return value ---------------------------- ---------- -------------- ------------ {} Profession Fisherman {} /--------------------------------------/ (same reference) { "Fisherman": {} } Group 6 {} /-------------------------------/ (same reference) { "Fisherman": { "6": {} } } Status Offer Accepted {}
object after first loop of data
{ "Fisherman": { "6": { "Offer Accepted": { "Count": 1 } } } }
Roundup: reduce
returns something, which is highly controllable.
Upvotes: 2
Reputation: 26181
Assuming your data is in this shape, one solution can be produced by using Array.prototype.reduce()
as follows;
var str = 'Group,Profession,Status,Count\n6,Fisherman,OfferAccepted,1\n6,Fisherman,All,1\n7,Fisherman,OfferAccepted,1\n7,Fisherman,All,1\n8,Banker,On Board,2\n8,Banker,All,2\n8,Cook,On Board,4\n8,Cook,All,4\n8,Developer,On Board,2\n8,Developer,All,2\n9,Banker,On Board,2\n9,Banker,OfferAccepted,1\n9,Banker,All,3',
data = str.split("\n").map(s => s.split(",")).slice(1),
jdata = data.reduce((p,c) => (p[c[1]] ? p[c[1]][c[0]] ? p[c[1]][c[0]][c[2]] = c[3]
: p[c[1]][c[0]] = {[c[2]]:c[3]}
: p[c[1]] = {[c[0]]:{[c[2]]:c[3]}},p),{});
document.write("<pre>" + JSON.stringify(jdata,null,2) + "</pre>");
Upvotes: 0
Reputation: 2404
You can do it quite easy with reduce:
const result = data.reduce((result, row) => {
ensureKeyExists(result, row.Profession);
ensureKeyExists(result[row.Profession], row.Group);
result[row.Profession][row.Group][row.Status] = row.Count;
return result;
}, {});
function ensureKeyExists(object, key, defaultVal = {}) {
if (!object[key]) {
object[key] = defaultVal;
}
}
Full example: https://jsfiddle.net/k1zk3ses/
Upvotes: 0
Reputation: 5002
Try this:
var result = new Array();
for(var d in data){
if(result[d.profession] == 'undefined'){
result[d.profession] = new Array();
}
if(result[d.profession][d.group] == 'undefined'){
result[d.profession][d.group] = new Array();
}
result[d.profession][d.group][d.status] = d.count;
}
result = JSON.stringify(result);//convert array to json
console.log(result);
I didn't test it and I supposed your JSON data are in data variable
Upvotes: 0