runnerpaul
runnerpaul

Reputation: 7236

Reduce count so that it shows a count for all suppliers per user

I have this object called grouped:

{ '1':
   [ { id: 1,
       name: 'John Doe',
       supplierName: 'Sup1',
       count: '21' } ],
  '2':
   [ { id: 2,
       name: 'Jane Doe',
       supplierName: 'Sup1',
       count: '95' } ],
  '3':
   [ { id: 3,
       name: 'Paul',
       supplierName: 'Sup1',
       count: '2' },
     { id: 3,
       name: 'Paul',
       supplierName: 'Sup2',
       count: '1' } 
    ] 
}

I create a users object with this:

    let users = _.map(grouped, userArray => ({
      id: userArray[0].id,
      name: userArray[0].name,
      suppliers: _.reduce(userArray, (accumulated, supplierObj) => {
        if (supplierObj.supplierName) {
          accumulated.push({
            title: supplierObj.supplierName,
          });
        }
        return accumulated;
      }, []),
    }));

It currently looks like this:

{
    "users": [
        {
            "id": 1,
            "name": "John Doe",
            "suppliers": [
                {
                    "title": "Sup1"
                }
            ]
        },{
            "id": 2,
            "name": "Jane Doe",
            "suppliers": [
                {
                    "title": "Sup1"
                }
            ]
        },{
            "id": 3,
            "name": "Paul",
            "suppliers": [
                {
                    "title": "Sup1"
                },{
                    "title": "Sup2"
                }
            ]
        }
    ]
}

I now want to add count in a way that my output is like this:

{
    "users": [
        {
            "id": 1,
            "name": "John Doe",
            "count": "21",
            "suppliers": [
                {
                    "title": "Sup1"
                }
            ]
        },{
            "id": 2,
            "name": "Jane Doe",
            "count": "95",
            "suppliers": [
                {
                    "title": "Sup1"
                }
            ]
        },{
            "id": 3,
            "name": "Paul",
            "count": "2",
            "suppliers": [
                {
                    "title": "Sup1"
                },{
                    "title": "Sup2"
                }
            ]
        }
    ]
}

If I simply add count: userArray[0].count, my output is correct for every user who has a single supplier but only picks the 1st for any with more than one. E.g. For the above, Paul would show a count of 2 and for Paul, there are 2 customers for Sup1 and 1 for Sup2. How do I fix this so users like Paul who have more than one supplier?

Upvotes: 0

Views: 32

Answers (3)

gregory
gregory

Reputation: 33

You can use map() and length()

users.map(user => ({
...user,
count: user.suppliers.length()
}))

Upvotes: -1

Maheer Ali
Maheer Ali

Reputation: 36594

You can use simple map(). And use reduce() to get count

let obj = { '1': [ { id: 1, name: 'John Doe', supplierName: 'Sup1', count: '21' } ], '2': [ { id: 2, name: 'Jane Doe', supplierName: 'Sup1', count: '95' } ], '3': [ { id: 3, name: 'Paul', supplierName: 'Sup1', count: '2' }, { id: 3, name: 'Paul', supplierName: 'Sup2', count: '1' } ] }

const res = Object.values(obj).map((x) => (
  { 
    id:x[0].id,
    name:x[0].name,
    suppliers:x.map(title => ({title})),
    count:x.reduce((ac,a) => +ac + +a.count, 0)
  }
))
console.log(res)

Upvotes: 1

Jonas Wilms
Jonas Wilms

Reputation: 138457

  count: userArray.reduce((sum, user) => sum + +user.count, 0)

Using .reduce you can sum up the counts. The unary plus is needed to cast the strings into numbers.

And you don't need lodash, and you don't need to reduce if you can filter and map:

  const users = Object.values(grouped).map(users => ({
     id: users[0].id,
     name: users[0].name,
     suppliers: users.map(user => user.supplierName).filter(it => it),
     count: users.reduce((sum, user) => sum + +user.count, 0),
  }));

Upvotes: 2

Related Questions