Ayushi Mishra
Ayushi Mishra

Reputation: 69

Merge two array of objects based on same key and value

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

Answers (5)

pilchard
pilchard

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

Arun Kumar Mohan
Arun Kumar Mohan

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

Ivan86
Ivan86

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

Brumor
Brumor

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

Md Sabbir Alam
Md Sabbir Alam

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

Related Questions