Reputation: 85
i have a data this data https://stackblitz.com/edit/react-26pgys how can i filter the json that i can get the first unique ID and last Unique ID
i have tried filtering the data like this
let pp = this.state.data.filter(
(ele, ind) => ind === this.state.data.findIndex(elem => elem.id === ele.id))
which filter all unique ids.
i would like the data result to be something like this
[{"id":"9000108","date":"2019-07-25","time":"17:49:23"},{"id":"9000108","date":"2019-07-25","time":"18:06:16"},{"id":"14947","date":"2019-07-25","time":"07:32:12"},{"id":"14947","date":"2019-07-31","time":"20:13:15"},{"id":"9000110","date":"2019-07-25","time":"07:25:10"},{"id":"9000110","date":"2019-07-31","time":"13:11:14"}, ....etc.]
Upvotes: 0
Views: 552
Reputation: 10224
If your data is sorted you can reduce
with a single iteration by keeping a reference on the previous id.
const data = [{"id":"9000108","date":"2019-07-25","time":"17:49:23"},{"id":"9000108","date":"2019-07-25","time":"18:06:16"},{"id":"14947","date":"2019-07-25","time":"07:32:12"},{"id":"14947","date":"2019-07-25","time":"07:32:15"},{"id":"14947","date":"2019-07-25","time":"07:32:18"},{"id":"14947","date":"2019-07-25","time":"16:26:24"},{"id":"14947","date":"2019-07-25","time":"20:09:53"},{"id":"14947","date":"2019-07-25","time":"20:09:56"},{"id":"14947","date":"2019-07-25","time":"20:10:07"},{"id":"14947","date":"2019-07-25","time":"20:13:49"},{"id":"14947","date":"2019-07-26","time":"06:40:48"},{"id":"14947","date":"2019-07-26","time":"06:40:51"},{"id":"14947","date":"2019-07-26","time":"10:31:31"},{"id":"14947","date":"2019-07-31","time":"20:13:08"},{"id":"14947","date":"2019-07-31","time":"20:13:15"},{"id":"9000110","date":"2019-07-25","time":"07:25:10"},{"id":"9000110","date":"2019-07-25","time":"07:25:12"},{"id":"9000110","date":"2019-07-25","time":"08:38:56"},{"id":"9000110","date":"2019-07-25","time":"08:51:54"},{"id":"9000110","date":"2019-07-25","time":"09:29:29"},{"id":"9000110","date":"2019-07-30","time":"13:01:36"},{"id":"9000110","date":"2019-07-30","time":"13:09:02"},{"id":"9000110","date":"2019-07-30","time":"13:19:58"},{"id":"9000110","date":"2019-07-30","time":"13:20:55"},{"id":"9000110","date":"2019-07-30","time":"14:14:09"},{"id":"9000110","date":"2019-07-30","time":"14:18:46"},{"id":"9000110","date":"2019-07-30","time":"16:16:47"},{"id":"9000110","date":"2019-07-30","time":"16:19:42"},{"id":"9000110","date":"2019-07-30","time":"16:21:39"},{"id":"9000110","date":"2019-07-30","time":"16:47:15"},{"id":"9000110","date":"2019-07-30","time":"16:53:48"},{"id":"9000110","date":"2019-07-30","time":"17:45:57"},{"id":"9000110","date":"2019-07-30","time":"17:48:55"},{"id":"9000110","date":"2019-07-30","time":"17:53:56"},{"id":"9000110","date":"2019-07-30","time":"17:56:03"},{"id":"9000110","date":"2019-07-30","time":"17:58:37"},{"id":"9000110","date":"2019-07-30","time":"20:13:29"},{"id":"9000110","date":"2019-07-30","time":"20:13:45"},{"id":"9000110","date":"2019-07-31","time":"07:33:59"},{"id":"9000110","date":"2019-07-31","time":"07:34:01"},{"id":"9000110","date":"2019-07-31","time":"07:53:13"},{"id":"9000110","date":"2019-07-31","time":"09:01:26"},{"id":"9000110","date":"2019-07-31","time":"10:12:33"},{"id":"9000110","date":"2019-07-31","time":"11:22:43"},{"id":"9000110","date":"2019-07-31","time":"11:23:03"},{"id":"9000110","date":"2019-07-31","time":"11:24:15"},{"id":"9000110","date":"2019-07-31","time":"11:28:30"},{"id":"9000110","date":"2019-07-31","time":"11:42:59"},{"id":"9000110","date":"2019-07-31","time":"11:54:20"},{"id":"9000110","date":"2019-07-31","time":"13:10:53"},{"id":"9000110","date":"2019-07-31","time":"13:11:14"}];
let previousId = data[0].id;
const result = data.reduce((acc, e, i) => {
if(previousId !== e.id) {
acc.push(data[i - 1], e);
previousId = e.id;
}
return acc;
}, [data[0]]);
// add the last item
result.push(data[data.length - 1]);
console.log(result);
Upvotes: 1
Reputation: 15688
Assuming your data is already organized chronologically, you could use array.reduce()
to shape your data. Then use Object.values()
and array.flatMap()
to create your unique array.
let dict = data.reduce((obj, item) => {
if(!obj[item.id]){
obj[item.id] = []
}
obj[item.id].push(item)
return obj
}, {})
let unique = Object.values(dict).flatMap((arr) => {
return [arr[0], arr[arr.length - 1]]
})
The result is an array with 32 items. 2 for each unique ID.
Upvotes: 1
Reputation: 185
It looks like you formulated your question a bit wrong? Probably, you meant this thing - "How to get a first and last records with the same id in array?". If I am right, this question doesn't belong to React, but to Native JavaScript. Here is an answer:
const formatted = this.state.data.reduce((acc, item) => {
// Check if there are no items with this ID in accumulator still
if (!acc.some(r => r.id === item.id)) {
// Find all records with same ID
const withSameId = records.filter(r => r.id === item.id);
acc.push(withSameId[0]);
if (withSameId.length > 1) {
acc.push(withSameId[withSameId.length - 1]);
}
}
return acc;
}, []);
You could optimize this script using something like cache (instead of using acc.some
we could use hashmap where key is id to make this check rather faster).
Upvotes: 1
Reputation: 1681
If you have lodash you can use findIndex and findLastIndex
const users = [
{ 'user': 'barney', 'active': true },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': true }
];
_.findIndex(users, function(o) { return o.active; });
// => 0
_.findLastIndex(users, function(o) { return o.active; });
// => 2
Upvotes: 0