1

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"
    }
]
Ivan86
  • 5,695
  • 2
  • 14
  • 30
Ayushi Mishra
  • 69
  • 1
  • 5
  • Does this answer your question? [Most efficient method to groupby on an array of objects](https://stackoverflow.com/questions/14446511/most-efficient-method-to-groupby-on-an-array-of-objects) – pilchard Mar 22 '21 at 12:42
  • Hi Ayushi, if an answer on this page solved your problem please consider marking it as accepted. And if you have the ability to upvote then upvoting answers that were useful to you is also a good idea. Thanks. – Ivan86 Mar 25 '21 at 03:50
  • By the way, [this](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) is how to accept an answer. – Ivan86 Mar 25 '21 at 07:37

5 Answers5

2

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);
Md Sabbir Alam
  • 4,937
  • 3
  • 15
  • 30
0

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)
Brumor
  • 95
  • 1
  • 9
0

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))
Arun Kumar Mohan
  • 11,517
  • 3
  • 23
  • 44
0

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);
Ivan86
  • 5,695
  • 2
  • 14
  • 30
0

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)
pilchard
  • 12,414
  • 5
  • 11
  • 23