0

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.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
elo-ly
  • 9
  • 1
  • check this article out it might be of help https://stackoverflow.com/a/54901360/11120306 – Curtis Crentsil Sep 22 '22 at 12:53
  • Why is id: 2, 3 , and 4 only one object in result? – zer00ne Sep 22 '22 at 13:00
  • *" I need to append the articles only when I click otherwise it will show all topics without articles."* It looks like each topic has articles. How are you actually handling the click event? Wouldn't it be easier to just reduce all articles into the topic they belong to then as the button is clicked only the topic that matches the button value is used? – zer00ne Sep 22 '22 at 13:22

2 Answers2

0

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);
Amila Senadheera
  • 12,229
  • 15
  • 27
  • 43
0

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))
jsBug
  • 348
  • 1
  • 9