0

I want to get the following output

expected output

[
  { name: 'mega-service', amount: [ 15, 22 ] },
  { name: 'somethingElse', amount: [ 12, 112 ] },
  { name: 'sms-alert', amount: [ 22 ] },
]

code i have written

const data = [
  {clientServiceName: "mega-service", amount: 15},
  {clientServiceName: "somethingElse", amount: 12},
  {clientServiceName: "somethingElse", amount: 112},
  {clientServiceName: "mega-service", amount: 22},
  {clientServiceName: "sms-alert", amount: 22}
]

const result = [];

data.forEach(d => {
  if(result.length === 0){
    let obj = {
      name: d.clientServiceName,
      amount: [d.amount]
    }
    result.push(obj);
  }else{
    result.forEach(r => {
      if(r.name === d.clientServiceName){
        r.amount = [...r.amount, d.amount]
        // console.log("inside name match")
      }else{
        let anotherObj = {
          name: d.clientServiceName,
          amount: [d.amount]
        }
        result.push(anotherObj);
      }
    })
  }
})

console.log(result)

But i am getting following output

output

[
  { name: 'mega-service', amount: [ 15, 22 ] },
  { name: 'somethingElse', amount: [ 12, 112 ] },
  { name: 'somethingElse', amount: [ 112 ] },
  { name: 'mega-service', amount: [ 22 ] },
  { name: 'mega-service', amount: [ 22 ] },
  { name: 'sms-alert', amount: [ 22 ] },
  { name: 'sms-alert', amount: [ 22 ] },
  { name: 'sms-alert', amount: [ 22 ] },
  { name: 'sms-alert', amount: [ 22 ] },
  { name: 'sms-alert', amount: [ 22 ] }
]

where did i get wrong here to get expected output. please help me to get my expected output

ggorlen
  • 44,755
  • 7
  • 76
  • 106
Shankar Ghimire
  • 138
  • 4
  • 15

5 Answers5

3

You can do with Array#reduce

const data = [ {clientServiceName: "mega-service", amount: 15}, {clientServiceName: "somethingElse", amount: 12}, {clientServiceName: "somethingElse", amount: 112}, {clientServiceName: "mega-service", amount: 22}, {clientServiceName: "sms-alert", amount: 22} ]


const res =  Object.values(data.reduce((acc,{clientServiceName:name,amount})=>(
   acc[name] = acc[name] || {name,amount:[]},
   acc[name]['amount'].push(amount)
   , acc
),{}))

console.log(res)
prasanth
  • 22,145
  • 4
  • 29
  • 53
  • I was in the process of writing something similar but this is *way* cleaner than I was going to do. I was going to check if the item existed and then either insert or append, but this is better. – Dillan Wilding Aug 15 '21 at 14:59
1

Use an object instead of array to group the common names, then use Object.values() to return array from that object

const data = [
  { clientServiceName: 'mega-service', amount: 15 },
  { clientServiceName: 'somethingElse', amount: 12 },
  { clientServiceName: 'somethingElse', amount: 112 },
  { clientServiceName: 'mega-service', amount: 22 },
  { clientServiceName: 'sms-alert', amount: 22 },
];

const group = {};

data.forEach(({ clientServiceName: name, amount }) => {  
  group[name] = group[name] || { name, amount: [] };
  group[name].amount.push(amount);
});

const res = Object.values(group);
console.log(res);
user000001
  • 32,226
  • 12
  • 81
  • 108
charlietfl
  • 170,828
  • 13
  • 121
  • 150
0

This does the job the way you wanted it.

let result = [];
data.forEach(item => {
    let index = result.findIndex(resultItem => resultItem.name === item.clientServiceName);
  if (index > -1) {
    result[index].amount.push(item.amount);
  } else {
    result.push({ name: item.clientServiceName, amount: [ item.amount ] });
  }
});
Harsh Mittal
  • 326
  • 3
  • 7
0

You can achieve the result by combination of reduce and find method

const data = [
  {clientServiceName: "mega-service", amount: 15},
  {clientServiceName: "somethingElse", amount: 12},
  {clientServiceName: "somethingElse", amount: 112},
  {clientServiceName: "mega-service", amount: 22},
  {clientServiceName: "sms-alert", amount: 22}
]


const answer = data.reduce((accum, cur) => {
  let obj = accum.find(x => x.name === cur.clientServiceName);

  
  if (obj) {
    obj.amount.push(cur.amount);
    return accum;
  } else {
    return [...accum, {name: cur.clientServiceName, amount: [cur.amount]}]
  }
}, [])

console.log(answer)
Isaac
  • 12,042
  • 16
  • 52
  • 116
-5

You can use the array.filter() function.

Look a the documentation :

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter