2

I'm trying to combine objects which share the same module key value, i.e. "credit cards". I need to return a single object per unique module with an array of distinct companies. The id and prod keys aren't important.

Here's the object I need to transform:

const data = [
   {module: "credit_cards", id: "1", company: "ABC", prod: "1"}, 
   {module: "credit_cards", id: "2", company: "XYZ", prod: "2"}, 
   {module: "credit_cards", id: "3", company: "EFG", prod: "2"}, 
   {module: "credit_cards", id: "2", company: "XYZ", prod: "2"}, 
   {module: "mortgages", id: "4", company: "EFG", prod: "3"}
]

I need to return something like this:

const result = [
{module: "credit_cards", company: ["ABC", "XYZ", "EFG"]}, 
{module: "mortgages", company: ["EFG"]}
]

So far, I've tried this function:

const result = data.reduce(function(r, e) {
  return Object.keys(e).forEach(function(k) {
    if(!r[k]) r[k] = [].concat(e[k])
    else r[k] = r[k].concat(e[k])
  }), r
}, {})

But it just concatenated all the key/values together...

Any help would be awesome, thanks :)

2
  • 2
    One key is company, while the others' keys are co_code, what's the logic behind that? Commented May 14, 2019 at 4:27
  • @CertainPerformance Good catch, that was a typo :) Commented May 14, 2019 at 4:30

5 Answers 5

3

You can use first Array.reduce() to group the companies by the module key on a Set. On a second step you can use array.Map() over the generated object .entries() to get the final desired result:

const data = [
   {module: "credit_cards", id: "1", company: "ABC", prod: "1"}, 
   {module: "credit_cards", id: "2", company: "XYZ", prod: "2"}, 
   {module: "credit_cards", id: "3", company: "EFG", prod: "2"}, 
   {module: "credit_cards", id: "2", company: "XYZ", prod: "2"}, 
   {module: "mortgages", id: "4", company: "EFG", prod: "3"}
];

let res = data.reduce((acc, {module, company}) =>
{
    acc[module] = acc[module] || new Set();
    acc[module].add(company);
    return acc;
}, {})

res = Object.entries(res).map(
    ([module, companies]) => ({module, company: [...companies]})
);

console.log(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

Sign up to request clarification or add additional context in comments.

Comments

3

Reduce into an object indexed by module, then take that object's values. Because you only want unique company values, use a Set initially, and then transform all items' company sets back into an array afterwards:

const data = [
   {module: "credit_cards", id: "1", company: "ABC", prod: "1"}, 
   {module: "credit_cards", id: "2", company: "XYZ", prod: "2"}, 
   {module: "credit_cards", id: "3", company: "EFG", prod: "2"}, 
   {module: "credit_cards", id: "2", company: "XYZ", prod: "2"}, 
   {module: "mortgages", id: "4", company: "EFG", prod: "3"}
]

const result = Object.values(data.reduce(
  (a, { module, company }) => {
    if (!a[module]) a[module] = { module, company: new Set() };
    a[module].company.add(company);
    return a;
  },
  {}
));

result.forEach((item) => {
  item.company = [...item.company];
});
console.log(result);

1 Comment

Note XYZ is duplicated on your co_code array. I believe, in relation to his desired output, he don't want duplicated values on the arrays.
3

You can use reduce to summarize the array into a Map. Use Set for unique values.

const data = [{"module":"credit_cards","id":"1","comapany":"ABC","prod":"1"},{"module":"credit_cards","id":"2","comapany":"XYZ","prod":"2"},{"module":"credit_cards","id":"3","comapany":"EFG","prod":"2"},{"module":"credit_cards","id":"2","comapany":"XYZ","prod":"2"},{"module":"mortgages","id":"4","comapany":"EFG","prod":"3"}]

const result = Array.from(data.reduce((c, {module,comapany}) => {
  if (!c.has(module)) c.set(module, new Set);
  c.get(module).add(comapany);
  return c;
}, new Map)).map(([module, comapany]) => ({module,comapany: [...comapany]}));

console.log(result);

Comments

0

Here is another approach with Array.reduce and with internal check to make sure the list of the companies is unique and without duplicates.

const data = [ {module: "credit_cards", id: "1", company: "ABC", prod: "1"}, {module: "credit_cards", id: "2", company: "XYZ", prod: "2"}, {module: "credit_cards", id: "3", company: "EFG", prod: "2"}, {module: "credit_cards", id: "2", company: "XYZ", prod: "2"}, {module: "mortgages", id: "4", company: "EFG", prod: "3"} ]

let result = data.reduce((r,{module, company}) => {
  r[module] = r[module] || { module, company: [] }
  if(!r[module].company.includes(company))
    r[module].company.push(company)
  return r
}, {})

console.log(Object.values(result))

Comments

0
   const data = [
  {module: 'credit_cards', id: '1', company: 'ABC', prod: '1'},
  {module: 'credit_cards', id: '2', company: 'XYZ', prod: '2'},
  {module: 'credit_cards', id: '3', company: 'EFG', prod: '2'},
  {module: 'credit_cards', id: '2', company: 'XYZ', prod: '2'},
  {module: 'mortgages', id: '4', company: 'EFG', prod: '3'}
  ];



 const result = data.reduce((array, item) => {
     const id = array.findIndex(el => el.module === item.module);
     if (id > -1) {
       array[id] = {...array[id], company : [...array[id].company, item.company]};
       return array;
     }
     return [...array, {...item, company : [ item.company]}];
    }, []);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.