Reduce an array of objects an keep only one object of each id depending on another data

Viewed 45

I'm pretty new to coding and I'm working on a problem. I can't fully understand how reduce function work. So basically I have an array of objects which are topics, each topic contains an article. When I click on a button it will append a topic. I need to append the articles only when I click otherwise it will show all topics without articles.

let buttonValue = 1;

const topics = [{
    id: 1,
    article: {"date" : "01-01-2022", "title" : "title1", "summary" : "summary1"}
  },
  {
    id: 2,
    article: {"date" : "01-01-2022", "title" : "title2", "summary" : "summary2"}
  },
  
  {
    id: 3,
    article: {"date" : "01-01-2022", "title" : "title3", "summary" : "summary3"}
  },
  {
    id: 4,
    article: {"date" : "01-01-2022", "title" : "title4", "summary" : "summary4"}
  },{
    id: 1,
    article: {"date" : "01-02-2022", "title" : "title5", "summary" : "summary5"}
  },
  {
    id: 2,
    article: {"date" : "01-02-2022", "title" : "title6", "summary" : "summary6"}
  },
  {
    id: 3,
    article: {"date" : "01-02-2022", "title" : "title7", "summary" : "summary7"}
  },
  {
    id: 1,
    article: {"date" : "01-02-2022", "title" : "title5", "summary" : "summary5"}
  },
];

Result should be:

const topics = [
  {
    id: 1,
    article: [{"date" : "01-01-2022", "title" : "title1", "summary" : "summary1"}, {"date" : "01-02-2022", "title" : "title5", "summary" : "summary5"}, {"date" : "01-02-2022", "title" : "title5", "summary" : "summary5"}]
 },
  {
    id: 4,
    article: {"date" : "01-01-2022", "title" : "title4", "summary" : "summary4"}
  },
  {
    id: 2,
    article: {"date" : "01-02-2022", "title" : "title6", "summary" : "summary6"}
  },
  {
    id: 3,
    article: {"date" : "01-02-2022", "title" : "title7", "summary" : "summary7"}
  },

];

Here is my code:

const articleArray = topics.reduce((acc,cur) => {
  const found = acc.find(topic => topic.id == cur.id && topic.id === buttonValue);
  return found ? found.article.push(cur.article) : acc.push({...cur, article:[cur.article]}), acc;
}, []);

const uniqueTopic = Array.from(new Set(articleArray.map(topic => topic.id)))
 .map(id => {
   return articleArray.find(element => element.id === id)
 })

I have some difficulties to understand how the reduce work because when I console log found it returned undefined. Can someone explain it? Is there another way to directly accumulate and reduce the array without uniqueTopic function? I tried:

const reducedArr = topics.reduce((acc, cur) => {
  acc[cur.id] && (cur.id === buttonValue)
    ? (acc[cur.id].push({...cur, article:[cur.article]}))
    : (acc[cur.id] = cur);
  return acc;
}, {});

It returned undefined.

2 Answers

can you check this once please

const topics = [{
    id: 1,
    article: {"date" : "01-01-2022", "title" : "title1", "summary" : "summary1"}
  },
  {
    id: 2,
    article: {"date" : "01-01-2022", "title" : "title2", "summary" : "summary2"}
  },
  
  {
    id: 3,
    article: {"date" : "01-01-2022", "title" : "title3", "summary" : "summary3"}
  },
  {
    id: 4,
    article: {"date" : "01-01-2022", "title" : "title4", "summary" : "summary4"}
  },{
    id: 1,
    article: {"date" : "01-02-2022", "title" : "title5", "summary" : "summary5"}
  },
  {
    id: 2,
    article: {"date" : "01-02-2022", "title" : "title6", "summary" : "summary6"}
  },
  {
    id: 3,
    article: {"date" : "01-02-2022", "title" : "title7", "summary" : "summary7"}
  },
  {
    id: 1,
    article: {"date" : "01-02-2022", "title" : "title5", "summary" : "summary5"}
  },
];
const fun = (ar)=>{
 const output = ar.reduce((prev, curr) => {
  const tmp = prev.find(e => e.id===curr.id);
    if (tmp) {
      tmp.article.push(curr.article)
    } else {
      prev.push({
       id : curr.id,
       article : [curr.article]
      });
    }
    return prev;
  }, []);
  return output
}
console.log(fun(topics))

One issue I noticed was no empty array had been initialized to push new items.

Try this to build the reduced array using Object.entries, Array.prototype.reduce, and Array.prototype.map.

const topics = [ { id: 1, article: { date: "01-01-2022", title: "title1", summary: "summary1" }, }, { id: 2, article: { date: "01-01-2022", title: "title2", summary: "summary2" }, }, { id: 3, article: { date: "01-01-2022", title: "title3", summary: "summary3" }, }, { id: 4, article: { date: "01-01-2022", title: "title4", summary: "summary4" }, }, { id: 1, article: { date: "01-02-2022", title: "title5", summary: "summary5" }, }, { id: 2, article: { date: "01-02-2022", title: "title6", summary: "summary6" }, }, { id: 3, article: { date: "01-02-2022", title: "title7", summary: "summary7" }, }, { id: 1, article: { date: "01-02-2022", title: "title5", summary: "summary5" }, }, ];

const reducedArr = Object.entries(
  topics.reduce((acc, cur) => {
    if (!acc[cur.id]) {
      acc[cur.id] = [];
    }
    acc[cur.id].push(cur.article);
    return acc;
  }, {})
).map(([id, articles]) => ({ id, articles }));

console.log(reducedArr);

Related