hackrack
hackrack

Reputation: 33

how to combine two different array of objects into one new array of object in javascript?

I have two arrays of objects with same news_ids but different properties, I am just wondering how to combine them and get a new array of objects?

For example:

let arr1 = [{
    news_id: 1,
    title: "title1"
  },
  {
    news_id: 2,
    title: "title2"
  },
  {
    news_id: 3,
    title: "title3"
  },
  {
    news_id: 4,
    title: "title4"
  },
]

let arr2 = [{
    news_id: 3,
    count: 3
  },
  {
    news_id: 4,
    count: 4
  }
]

And I would like to get:

[
  {news_id: 1, title: "title1", count: 0},
  {news_id: 2, title: "title2", count: 0},
  {news_id: 3, title: "title3", count: 3},
  {news_id: 4, title: "title4", count: 4}
]

Upvotes: 2

Views: 121

Answers (5)

Nina Scholz
Nina Scholz

Reputation: 386540

You could take a Map for collecting all given data and the counts. Then render the final result.

var array1 = [{ news_id: 1, title: "title1" }, { news_id: 2, title: "title2" }, { news_id: 3, title: "title3" }, { news_id: 4, title: "title4" }],
    array2 = [{ news_id: 3, count: 3 }, { news_id: 4, count: 4 }],
    result = Array.from(
        array2
            .reduce(
                (m, { news_id, count }) => (m.get(news_id).count += count, m),
                array1.reduce((m, o) => m.set(o.news_id, Object.assign({}, o, { count: 0 })), new Map)
            )
            .values()
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 0

Mohan Rajput
Mohan Rajput

Reputation: 642

In your case to get the desired result.I recommend you should try old school JS forEach() Method.

And here is the example done check it on JS Fiddle Example

let arr1 = [{
    news_id: 1,
    title: "title1"
  },
  {
    news_id: 2,
    title: "title2"
  },
  {
    news_id: 3,
    title: "title3"
  },
  {
    news_id: 4,
    title: "title4"
  }
]

let arr2 = [
    {
    news_id: 3,
    count: 3
  },
  {
    news_id: 4,
    count: 4
  }
]


arr1.forEach(function (e,i) {
    var flag = false;
  arr2.forEach(function (obj, j) {
        if (e.news_id === obj.news_id) {
            e.count = obj.count;
      flag = true;
        }
    });
  if(!flag){
    e.count = 0;
  }
});

Upvotes: 1

Karan
Karan

Reputation: 12619

You can do that with forEach and filter as below:

arr1.forEach(i => i.count = (arr2.find(j => j.news_id == i.news_id) || { count: 0 }).count)

Try it below.

let arr1 = [{
    news_id: 1,
    title: "title1"
  },
  {
    news_id: 2,
    title: "title2"
  },
  {
    news_id: 3,
    title: "title3"
  },
  {
    news_id: 4,
    title: "title4"
  },
]

let arr2 = [{
    news_id: 3,
    count: 3
  },
  {
    news_id: 4,
    count: 4
  }
]

arr1.forEach(i => i.count = (arr2.find(j => j.news_id == i.news_id) || { count: 0 }).count);
console.log(arr1);

Upvotes: 2

Cobus Kruger
Cobus Kruger

Reputation: 8605

Here is a simpler solution. I simply iterate arr1 and add the count from the matching arr2 item, if any.

for (item of arr1) {
    let arr2item = arr2.find(item2 => item2.news_id === item.news_id);
  item['count'] = arr2item ? arr2item.count : 0;
};

@Nitish's answer looks good, but the intention is not very clear.

Upvotes: 0

Nitish Narang
Nitish Narang

Reputation: 4184

This can be done as follows. Also this is generic and will concat all properties for same news_id, not just count and title.

let arr1 = [
              {news_id: 1, title: "title1"},
              {news_id: 2, title: "title2"},
              {news_id: 3, title: "title3"},
              {news_id: 4, title: "title4"},
           ]


let arr2 = [
             {news_id: 3, count: 3},
             {news_id: 4, count: 4}
           ]

let result = Object.values(([...arr1, ...arr2].reduce((acc, d) => (acc[d.news_id] = { count:0, ...acc[d.news_id], ...d }, acc) ,{})))

Upvotes: 2

Related Questions