Reputation: 527
This question has been asked in many different forms, but I haven't been able to piece it all together to achieve the outcome I'm looking for. So, sorry for duplicating the duplicates...
What I'm wanting to do is take an Array like this:
[
0: {
2014: "6",
2015: "19",
2016: "3",
2017: "12",
Name: "Jerry"
},
1: {
2014: "16",
2015: "9",
2016: "",
2017: "16",
Name: "Bill"
},
2: {
2014: "",
2015: "2",
2016: "43",
2017: "7",
Name: "Grace"
}
]
Into something like this:
{
"years": {
"2014": {
"Jerry": 6,
"Bill": 16,
"Grace": ""
},
"2015": {
"Jerry": 19,
"Bill": 9,
"Grace": 2
},
"2016": {
"Jerry": 3,
"Bill": "",
"Grace": 43
},
"2017": {
"Jerry": 12,
"Bill": 16,
"Grace": 7
}
}
}
Bit of Code I still have after trying stuff, deleting, repeat, repeat...:
FYI - data is from CSV file being loaded from D3.js csv()
let loadData = () => {
return d3.csv(dataFile, function cb (err, d) {
if (err) throw err;
return d;
});
};
loadData().get((err, n) => {
if (err) throw err;
let years = [];
years.push(Object.keys(n[0]));
years = _.flatten(years);
years.splice(-1, 1);
console.log(n[0]);
n.map((x) => {
console.log(Object.keys(x[0]));
});
});
Upvotes: 0
Views: 69
Reputation: 8661
reduce
is not mandatory. For instance:
let result = { years : {} };
for (let record of input) {
for (let key in record) {
if (key == 'Name') continue;
result.years[key] = result.years[key] || {};
result.years[key][record.Name] = record[key];
}
}
Upvotes: 0
Reputation: 2294
You can use Array.prototype.reduce
method for this scenario. First parameter to this method is a reducer and the second one is initial value.
var input = [{
2014: "6",
2015: "19",
2016: "3",
2017: "12",
Name: "Jerry"
},
{
2014: "16",
2015: "9",
2016: "",
2017: "16",
Name: "Bill"
},
{
2014: "",
2015: "2",
2016: "43",
2017: "7",
Name: "Grace"
}
];
var output = input.reduce((a, b) => {
for (var k in b) {
if (k !== 'Name') {
a.year[k] = a.year[k] || {};
a.year[k][b.Name] = b[k];
}
}
return a;
}, {
years: {}
});
console.log(output);
Upvotes: 0
Reputation: 122047
You can use reduce()
to build object and inside you can use Object.keys()
and forEach()
loop to add object for each year.
var arr = [{"2014":"6","2015":"19","2016":"3","2017":"12","Name":"Jerry"},{"2014":"16","2015":"9","2016":"","2017":"16","Name":"Bill"},{"2014":"","2015":"2","2016":"43","2017":"7","Name":"Grace"}]
var result = arr.reduce(function(r, o) {
Object.keys(o).forEach(function(e) {
if(!r.years[e] && e != 'Name') r.years[e] = {}
Object.assign(r.years[e] || {}, {[o.Name]: o[e]})
})
return r;
}, {years: {}})
console.log(JSON.stringify(result, 0, 4))
Upvotes: 0
Reputation: 5344
You can use "reduce" to achieve this.
var data = [{
2014: "6",
2015: "19",
2016: "3",
2017: "12",
Name: "Jerry"
}, {
2014: "16",
2015: "9",
2016: "",
2017: "16",
Name: "Bill"
}, {
2014: "",
2015: "2",
2016: "43",
2017: "7",
Name: "Grace"
}];
data = data.reduce(function(pre, v) {
for (var i in v) {
if (i === 'Name') {
continue;
}
if (!pre[i]) {
pre[i] = {};
};
pre[i][v.Name] = v[i];
}
return pre;
}, {});
data = {
years: data
};
console.log(data);
Upvotes: 2
Reputation: 386578
You could iterating the array and the keys and build a new object.
var data = [{ 2014: "6", 2015: "19", 2016: "3", 2017: "12", Name: "Jerry" }, { 2014: "16", 2015: "9", 2016: "", 2017: "16", Name: "Bill" }, { 2014: "", 2015: "2", 2016: "43", 2017: "7", Name: "Grace" }],
grouped = { years: {} };
data.forEach(function (o) {
Object.keys(o).forEach(function (k) {
if (k !== 'Name') {
grouped.years[k] = grouped.years[k] || {};
grouped.years[k][o.Name] = o[k];
}
});
});
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1