I have a dataset like this:
var dataset = [
{time: "t1", locA: "a1", locB: "b1", value: v1},
{time: "t1", locA: "a1", locB: "b2", value: v2},
{time: "t1", locA: "a2", locB: "b1", value: v3},
{time: "t1", locA: "a2", locB: "b2", value: v4},
{time: "t2", locA: "a1", locB: "b1", value: v5},
{time: "t2", locA: "a1", locB: "b2", value: v6},
{time: "t2", locA: "a2", locB: "b1", value: v7},
{time: "t2", locA: "a2", locB: "b2", value: v8},
....
];
I want a result like this:
var a1b1 = [
{loc: "a1b1", time: "t1", value: "v1"},
{loc: "a1b1", time: "t2", value: "v5"},
....
];
var a1b2 = [
{loc: "a1b2", time: "t1", value: "v2"},
{loc: "a1b2", time: "t2", value: "v6"},
....
];
var a2b1 = [
{loc: "a2b1", time: "t1", value: "v3"},
{loc: "a2b1", time: "t2", value: "v7"},
....
];
var a2b2 = [
{loc: "a2b2", time: "t1", value: "v4"},
{loc: "a2b2", time: "t2", value: "v8"},
....
];
It's important that the t values are in the correct order while it represents time. I cannot use libraries, just vintage JavaScript. I found some older SO posts with splitting an array of objects but they describe just simple splitting or using libraries.
Is it possible with forEach like
dataset.forEach(function()...
Any help is appreciated..
Another short Array.prototype.reduce()
approach:
var dataset = [
{time: "t1", locA: "a1", locB: "b1", value: "v1"}, {time: "t1", locA: "a1", locB: "b2", value: "v2"}, {time: "t1", locA: "a2", locB: "b1", value: "v3"},
{time: "t1", locA: "a2", locB: "b2", value: "v4"}, {time: "t2", locA: "a1", locB: "b1", value: "v5"}, {time: "t2", locA: "a1", locB: "b2", value: "v6"}, {time: "t2", locA: "a2", locB: "b1", value: "v7"}, {time: "t2", locA: "a2", locB: "b2", value: "v8"}
];
var result = dataset.reduce(function(r, o){
var k = o.locA + o.locB; // unique `loc` key
if (r[k] || (r[k]=[])) r[k].push({loc:k, time: o.time, value: o.value});
return r;
}, {});
console.log(result);
You can use reduce
to group the objects:
function group(arr) {
return arr.reduce(function(res, obj) { // for each object obj in the array arr
var key = obj.locA + obj.locB; // let key be the concatination of locA and locB
var newObj = {loc: key, time: obj.time, value: obj.value}; // create a new object based on the object obj
if(res[key]) // if res has a sub-array for the current key then...
res[key].push(newObj); // ... push newObj into that sub-array
else // otherwise...
res[key] = [ newObj ]; // ... create a new sub-array for this key that initially contain newObj
return res;
}, {});
}
var result = group([
{time: "t1", locA: "a1", locB: "b1", value: "v1"},
{time: "t1", locA: "a1", locB: "b2", value: "v2"},
{time: "t1", locA: "a2", locB: "b1", value: "v3"},
{time: "t1", locA: "a2", locB: "b2", value: "v4"},
{time: "t2", locA: "a1", locB: "b1", value: "v5"},
{time: "t2", locA: "a1", locB: "b2", value: "v6"},
{time: "t2", locA: "a2", locB: "b1", value: "v7"},
{time: "t2", locA: "a2", locB: "b2", value: "v8"}
]);
console.log(result);
Note: Instead of assigning the values to separate variables a1b1
, a1b2
, ... (which won't be very flexible and dynamic), my answer groups the results into one big object that contain the arrays (results) under their equivalent keys. So result
is like this:
result = {
"a1b1": [ ... ],
"a1b2": [ ... ],
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With