Reputation: 69
I have an array that looks like this:
[
{
like_id: 1,
likes: 1,
post_id: 1,
type: "feed_post_likes",
_id: "b51771798ed01795cb8a17b028000329"
},
{
post_id: 1,
created_date: "2021-03-10T10:54:35.264Z",
post_message: "Happy",
post_pic: "",
post_type: "post"
}
]
I need to merge these array based on post_id and get this:
[
{
like_id: 1,
likes: 1,
post_id: 1,
type: "feed_post_likes",
_id: "b51771798ed01795cb8a17b028000329",
created_date: "2021-03-10T10:54:35.264Z",
post_message: "Happy",
post_pic: "",
post_type: "post"
}
]
Upvotes: 1
Views: 140
Reputation: 12956
Here is an option using a Map
, iterating the input using a for...of
loop and merging objects with the same post.id
using Object.assign()
. The result is the .values()
iterator of the Map
converted to an array.
const input = [{ like_id: 1, likes: 1, post_id: 1, type: "feed_post_likes", _id: "b51771798ed01795cb8a17b028000329" }, { post_id: 1, created_date: "2021-03-10T10:54:35.264Z", post_message: "Happy", post_pic: "", post_type: "post" }];
const grouped = new Map(input.map(like => [like.post_id, {}]));
for (let like of input) {
Object.assign(grouped.get(like.post_id), like);
}
const result = [...grouped.values()];
console.log(result)
Upvotes: 0
Reputation: 11915
You can use Array.prototype.reduce
to merge objects with the same post_id
and then use Object.values
to get an array of the merged objects.
const items = [
{ like_id: 1, likes: 1, post_id: 1, type: 'feed_post_likes', _id: 'b51771798ed01795cb8a17b028000329' },
{ post_id: 1, created_date: '2021-03-10T10:54:35.264Z', post_message: 'Happy', post_pic: '', post_type: 'post' }
]
const result = items.reduce((acc, item) => ({
...acc,
[item.post_id]: {
...acc[item.post_id] || {},
...item
}
}), {})
console.log(Object.values(result))
Upvotes: 0
Reputation: 5708
You can iterate through the array of objects storing every post_id
that has already been processed and for those that haven't yet been processed you can use array.filter()
to return an array of objects that have a given post_id
and then array.reduce()
to merge all the objects into one using Object.assign()
:
var arr = [
{
like_id: 1,
likes: 1,
post_id: 1,
type: "feed_post_likes",
_id: "b51771798ed01795cb8a17b028000329"
},
{
post_id: 1,
created_date: "2021-03-10T10:54:35.264Z",
post_message: "Happy",
post_pic: "",
post_type: "post"
}
];
let processed = [];
let result = [];
for(obj in arr) {
if(processed.indexOf(arr[obj].post_id) < 0) {
processed.push(arr[obj].post_id);
result.push(arr.filter(item => item.post_id == arr[obj].post_id)
.reduce((acc, currVal) => Object.assign(acc, currVal), {}));
}
}
console.log(result);
Upvotes: 0
Reputation: 95
Here is a solution I propose:
const arrayTest = [
{like_id: 1, likes: 1, post_id: 1, type: "feed_post_likes", _id: "b51771798ed01795cb8a17b028000329"},
{post_id: 1, created_date: "2021-03-10T10:54:35.264Z", post_message: "Happy", post_pic: "", post_type: "post"}
]
const result = arrayTest.reduce((acc, curr) => {
const hasIdAlready = acc.some(e => e.post_id === curr.post_id);
if (hasIdAlready) {
return acc
}
const foundMatchingElems = arrayTest.filter(e => e.post_id === curr.post_id)
const mergedObjects = foundMatchingElems.reduce((obj, e) => ({...obj, ...e}), {})
return [...acc, mergedObjects]
}, [])
console.log(result)
Upvotes: 0
Reputation: 5064
You can do the following using array reduce method,
arr = [
{
like_id: 1,
likes: 1,
post_id: 1,
type: "feed_post_likes",
_id: "b51771798ed01795cb8a17b028000329"
},
{
post_id: 1,
created_date: "2021-03-10T10:54:35.264Z",
post_message: "Happy",
post_pic: "",
post_type: "post"
}
];
ret = arr.reduce((prev, curr) => {
const idx = prev.findIndex(item => item.post_id === curr.post_id);
if(idx > -1) {
prev[idx] = {...prev[idx], ...curr};
} else {
prev.push(curr);
}
return prev;
}, [])
console.log(ret);
Upvotes: 2