I need to convert the following array of objects into a an object format when topic = 'favorites'.
Original Format
const events = [
{
topic: 'favorites',
receiver: '1000066928',
datetime: 2016-11-26T21:43:54.000Z
},
{
topic: 'favorites',
receiver: '1000061499',
datetime: 2017-01-03T19:15:04.000Z
},
{
topic: 'blocked',
receiver: '1000102733',
datetime: 2017-01-05T17:04:15.000Z
},
{
topic: 'blocked',
receiver: '1000107928',
datetime: 2017-01-06T17:17:05.000Z
}
]
Converted Format
{
1000000002: '2020-01-24T20:46:05+11:00',
1000000008: '2020-01-24T20:46:05+11:00',
1000000009: '2020-01-24T20:46:05+11:00',
1000000010: '2020-01-24T20:46:05+11:00'
},
I've been trying to work with the following but I'm a bit off.
events.filter((event) => event.topic === "favorites").map(receiver, datetime => receiver: datetime)
You could filter and map the entries for a new object.
const events = [{ topic: 'favorites', receiver: '1000066928', datetime: '2016-11-26T21:43:54.000Z' }, { topic: 'favorites', receiver: '1000061499', datetime: '2017-01-03T19:15:04.000Z' }, { topic: 'blocked', receiver: '1000102733', datetime: '2017-01-05T17:04:15.000Z' }, { topic: 'blocked', receiver: '1000107928', datetime: '2017-01-06T17:17:05.000Z' }], result = Object.fromEntries(events.filter(({ topic }) => topic === 'favorites').map(({ receiver, datetime }) => [receiver, datetime]) ); console.log(result);
Your given data doesn't correspond to your expected output by value . But I assume the format is correct. It also seems like, in your result, you want the dates in ISO string form. But in your source object they are kept as a Date
object. So I'll be assuming the source array does indeed contain Date
objects.
With that said, you really just have to turn every object into [receiver, datetime]
(after filtering) and do Object.fromEntries
on the result
const result = Object.fromEntries(
events
.filter(event => event.topic === 'favorites')
.map(({ receiver, datetime }) => [receiver, datetime.toISOString()])
);
const events = [ { topic: 'favorites', receiver: '1000066928', datetime: new Date('2016-11-26T21:43:54.000Z'), }, { topic: 'favorites', receiver: '1000061499', datetime: new Date('2017-01-03T19:15:04.000Z'), }, { topic: 'blocked', receiver: '1000102733', datetime: new Date('2017-01-05T17:04:15.000Z'), }, { topic: 'blocked', receiver: '1000107928', datetime: new Date('2017-01-06T17:17:05.000Z'), }, ]; const result = Object.fromEntries( events.filter(event => event.topic === 'favorites').map(({ receiver, datetime }) => [receiver, datetime.toISOString()]) ); console.log(result);
With reduce
you can built an object that will be updated in every iteration.
const output = events
.filter((event) => event.topic === "favorites")
.reduce((acc, cur) => {
return {...acc, [cur.receiver]: cur.datetime };
}, {});
console.log(output);
/* {
'1000061499': '2017-01-03T19:15:04.000Z',
'1000066928': '2016-11-26T21:43:54.000Z'
}
*/
you can use reduce and filter for this in combination
I had to do a string out of datetime otherwise it would result in an error.
const events = [ { topic: 'favorites', receiver: '1000066928', datetime: "2016-11-26T21:43:54.000Z" }, { topic: 'favorites', receiver: '1000061499', datetime: "2017-01-03T19:15:04.000Z" }, { topic: 'blocked', receiver: '1000102733', datetime: "2017-01-05T17:04:15.000Z" }, { topic: 'blocked', receiver: '1000107928', datetime: "2017-01-06T17:17:05.000Z" } ] const result = events.filter((event) => event.topic === "favorites").reduce((accum, element) => { return {...accum, [element.receiver]: element.datetime }; }, {}); console.log(result);
You can use reduce
like this:
const filteredEvents = events.reduce((a, b) => {
return b.topic === 'favorites'
? {...a, [b.receiver] : b.datetime}
: a
}, {})
console.log(filteredEvents);
/*
{
'1000061499': '2017-01-03T19:15:04.000Z',
'1000066928': '2016-11-26T21:43:54.000Z'
}
*/
This is a classic use case for using the .reduce()
prototype function on the array. This will save you multiple repeated iterations with fewer lines of code.
The example data doesn't seem to match but I am assuming the format is correct.
In your case, you can use reduce
like this -
const events = [
{
topic: 'favorites',
receiver: '1000066928',
datetime: new Date('2016-11-26T21:43:54.000Z'),
},
{
topic: 'favorites',
receiver: '1000061499',
datetime: new Date('2017-01-03T19:15:04.000Z'),
},
{
topic: 'blocked',
receiver: '1000102733',
datetime: new Date('2017-01-05T17:04:15.000Z'),
},
{
topic: 'blocked',
receiver: '1000107928',
datetime: new Date('2017-01-06T17:17:05.000Z'),
},
];
const result = events.reduce((acc, event) => {
if (b.topic === 'favorites') {
return {...acc, [event.receiver] : b.datetime};
}
return acc;
}, {})
console.log(result);
To better understand how reduce works - https://www.freecodecamp.org/news/reduce-f47a7da511a9/
A one line reducer should be sufficient
const events = [{ topic: 'favorites', receiver: '1000066928', datetime: "2016-11-26T21:43:54.000Z" }, { topic: 'favorites', receiver: '1000061499', datetime: "2017-01-03T19:15:04.000Z" }, { topic: 'blocked', receiver: '1000102733', datetime: "2017-01-05T17:04:15.000Z" }, { topic: 'blocked', receiver: '1000107928', datetime: "2017-01-06T17:17:05.000Z" } ] console.log(events.reduce((acc, val) => val.topic === "favorites" && {...acc, [val.receiver]: val.datetime } || acc, {}));
A single reduce combined with a topic filter should be enough and some answers have already demonstrated how to do this.
This answer does that but adds:
const transform =
topic => xs =>
xs.reduce( (o, x) =>
(x.topic === topic
? (o[x.receiver] = x.datetime, o)
: o), {});
What's going on here?
The function is curried; it takes a topic then a list to process. This means you can build two topic-processing functions:
const favorites = transform('favorites');
const blocked = transform('blocked');
These two functions now only wait for a list to be processed. Assuming list
is the same as your events
array:
favorites(list);
// { 1000061499: "2017-01-03T19:15:04.000Z"
// , 1000066928: "2016-11-26T21:43:54.000Z"
// }
blocked(list);
// { 1000102733: "2017-01-05T17:04:15.000Z"
// , 1000107928: "2017-01-06T17:17:05.000Z"
// }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.