-2

I know this could have been solved easily from backend but was curious to know if there is any efficient way to solve this issue from front end using js.

I have an array

[
 {  
    id: 11
    ruleDesc: "rule 1 "
 },
{  
    id: 15
    ruleDesc: "rule 2 "
 },
{  
    id: 12
    ruleDesc: "rule 3 "
 },
{  
    id: 11
    ruleDesc: "rule 4 "
 },
{  
    id: 11
    ruleDesc: "rule 5 "
 },

]

What I'm expecting is

[
  {  
        id: 11
        ruleDesc: "rule 1 "
        ruleDesc: "rule 4 "
        ruleDesc: "rule 5 "
     },
{  
        id: 12
        ruleDesc: "rule 3 "
     },
{  
        id: 15
        ruleDesc: "rule 2 "
     },
]
Feroz
  • 173
  • 1
  • 10

2 Answers2

1

You need to create an array of ruleDesc for same group. Because an object can't have same keys.

You can use reduce() to get an object and then use Object.values to get an array.

const arr = [ { id: 11, ruleDesc: "rule 1 " }, { id: 15, ruleDesc: "rule 2 " }, { id: 12, ruleDesc: "rule 3 " }, { id: 11, ruleDesc: "rule 4 " }, { id: 11, ruleDesc: "rule 5 " } ]

const res = arr.reduce((ac,{id,ruleDesc}) => {
  ac[id] = ac[id] || {id,ruleDesc:[]}
  ac[id].ruleDesc.push(ruleDesc);
  return ac;
},{})
console.log(Object.values(res))
Maheer Ali
  • 35,834
  • 5
  • 42
  • 73
1

This is similar to the answer from Masheer Ali, but I think the reduction is a little nicer:

const transform = arr => Object .values (arr .reduce ((a, {id, ruleDesc}) => 
  ({...a, [id]: {id, ruleDesc: [...( (a [id] || {}) .ruleDesc || [] ), ruleDesc]}}),
  {}
))

const rules = [{id: 11, ruleDesc: "rule 1 "}, {id: 15, ruleDesc: "rule 2 "}, {id: 12, ruleDesc: "rule 3 "}, {id: 11, ruleDesc: "rule 4 "}, {id: 11, ruleDesc: "rule 5 "}]

console .log (
  transform (rules)
)

One advantage is that if you have additional properties you want to merge, it's only a minor tweak:

const transform = arr => Object .values (arr .reduce ((a, {id, ruleDesc, ...rest}) => 
  ({...a, [id]: {...(a[id] || {}), id,  ruleDesc: [...((a[id] || {}).ruleDesc || []) , ruleDesc], ...rest}}),
  {}
))
Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103