Reputation: 31
I have an array of objects like these
[
{
id: 536,
user_id: 87,
event_type: 'CA',
purpose: 1,
timestamp: 1435678384
},
{
id: 5368,
user_id: 87,
event_type: 'CA',
purpose: 4,
timestamp: 1435678384
},
{
id: 53688,
user_id: 87,
event_type: 'CA',
purpose: 9,
timestamp: 1435678385
},
{
id: 588,
user_id: 87,
event_type: 'CA',
purpose: 7,
timestamp: 1435678386
},
{
id: 588,
user_id: 87,
event_type: 'CA',
purpose: 5,
timestamp: 1435678396
},
{
id: 588,
user_id: 87,
event_type: 'CA',
purpose: 8,
timestamp: 1435678397
},
{
id: 588,
user_id: 87,
event_type: 'CA',
purpose: 2,
timestamp: 1435678398
},
{
id: 588,
user_id: 87,
event_type: 'CA',
purpose: 3,
timestamp: 1435678350
}
]
I want to group all the objects inside the array by their timestamp, so if the timestamps in the objects are located within 5ms of each other, combine the objects into one single array
So in this case I want the output to look like
[
[{
id: 536,
user_id: 87,
event_type: 'CA',
purpose: 1,
timestamp: 1435678384
},
{
id: 5368,
user_id: 87,
event_type: 'CA',
purpose: 4,
timestamp: 1435678384
},
{
id: 53688,
user_id: 87,
event_type: 'CA',
purpose: 9,
timestamp: 1435678385
},
{
id: 588,
user_id: 87,
event_type: 'CA',
purpose: 7,
timestamp: 1435678386
}
],
[{
id: 588,
user_id: 87,
event_type: 'CA',
purpose: 5,
timestamp: 1435678396
},
{
id: 588,
user_id: 87,
event_type: 'CA',
purpose: 8,
timestamp: 1435678397
},
{
id: 588,
user_id: 87,
event_type: 'CA',
purpose: 2,
timestamp: 1435678398
}
], {
id: 588,
user_id: 87,
event_type: 'CA',
purpose: 3,
timestamp: 1435678350
}
]
I have tried to use an array method filter on this to get the desired code. However I can only segregate one group, I cannot have a 2D array like this. Notice the last object which cannot be grouped(timestamp is far beyond 5ms of any other object's timestamp) is not in an array.
My efforts so far are not much, Here is what I have tried
ca.forEach((cur, index) => {
let newArr = []
let grouped = ca.filter((target, innerIndex) => {
if ((cur.timestamp - target.timestamp) < 5) {
return true
} else {
return false
}
})
Any help to solve this will be greatly appreciated!
Upvotes: 0
Views: 154
Reputation: 912
What you can try is the reduce function: see here my code in stackblitz
var firstArray = [
{
id: 536,
user_id: 87,
event_type: 'CA',
purpose: 1,
timestamp: 1435678384
},
{
id: 5368,
user_id: 87,
event_type: 'CA',
purpose: 4,
timestamp: 1435678384
},
{
id: 53688,
user_id: 87,
event_type: 'CA',
purpose: 9,
timestamp: 1435678385
},
{
id: 588,
user_id: 87,
event_type: 'CA',
purpose: 7,
timestamp: 1435678386
},
{
id: 588,
user_id: 87,
event_type: 'CA',
purpose: 5,
timestamp: 1435678396
},
{
id: 588,
user_id: 87,
event_type: 'CA',
purpose: 8,
timestamp: 1435678397
},
{
id: 588,
user_id: 87,
event_type: 'CA',
purpose: 2,
timestamp: 1435678398
},
{
id: 588,
user_id: 87,
event_type: 'CA',
purpose: 3,
timestamp: 1435678350
}
];
var secondArray = firstArray.sort((a, b)=>{
return a.timestamp-b.timestamp
}).reduce(
(accumulator,current)=>{
if(
typeof accumulator[accumulator.length-1]==='object' &&
current.timestamp - accumulator[accumulator.length-1][0].timestamp <5
) {
accumulator[accumulator.length-1].push(current);
} else {
accumulator.push([current]);
}
return accumulator;
},
[]
);
console.log(secondArray);
EDIT: I didn't see the 5 ms need but you can adapt the if
to suit your need, tell me if you want me to do it. ;)
EDIT2: I added the sort function in order to sort by timestamp like that we're sure the minus operation is in the good order and I did the minus operation in the if of the reduce. Let me know if that helps
Upvotes: 2
Reputation:
You can create one big array. And small reusable array that you put all the objects that are related and then push the tempArray to the allArray Array and clear it and then do the same for all the other objects. Get all the object with that certain property using the foreach method of the array.
Let allArray = [ ];
Let tempArray = [ ];
allArray.push(tempArray);
Upvotes: 0