javascriptdictionarykeyadditionreduce

Add key/value to dict in map method


I have this code:

results = "[ { user_name: 'User 1',
    email: 'user1@email.com',
    userid: 'HJ10092',
    event_type: 'download',
    country: 'Venezuela',
    doc_type: 'mspowerpoint',
    total: '1' },
  { user_name: 'User 1',
    email: 'user1@email.com',
    userid: 'HJ10092',
    event_type: 'download',
    country: 'Venezuela',
    doc_type: 'document',
    total: '1' },
  { user_name: 'User 1',
    email: 'user1@email.com',
    userid: 'HJ10092',
    event_type: 'download',
    country: 'Venezuela',
    doc_type: 'msword',
    total: '2' },
  { user_name: 'User 2',
    email: 'user2@email.com',
    userid: 'POG0092',
    event_type: 'download',
    country: 'Spain',
    doc_type: 'png',
    total: '3' },
  { user_name: 'User 2',
    email: 'user2@email.com',
    userid: 'POG0092',
    event_type: 'download',
    country: 'Spain',
    doc_type: 'txt',
    total: '3' }]"


  const groupedDocs = Object.entries(
    results.reduce((acc, { country, email, doc_type, total }) => {
      // Group initialization
      grouping = email[0].v
      if (!acc[grouping]) {
        acc[grouping] = [];
      }
      // Grouping
      // FIX: only pushing the object that contains id and value
      acc[grouping].push({ doc_type, total});
      return acc;
    }, {})

  ).map(([email, count]) => ({ email, count }));
  console.log(".......................>>>>", JSON.stringify(groupedDocs));

It does what I want, but I need to also include the "country" field for each user, and I can't. Something like that:

[
 { "email": "user1@email.com",
  "country":"Venezuela",
  "count":[{"doc_type":"mspowerpoint",
  "total":"1"
},
{
  "doc_type":"document",
  "total":"1"
},
{
  "doc_type":"txt",
  "total":"69"
},
{
  "doc_type":"pdf",
  "total":"328"
   }
  ]
 },
 { "email": "user2@email.com",
  "country":"Spain",
  "count":[{"doc_type":"mspowerpoint",
  "total":"1"
},
{
  "doc_type":"document",
  "total":"1"
},
{
  "doc_type":"txt",
  "total":"69"
}]}]

I could add the country field to each document type, but I don't want to repeat it so many times. I want it to be an additional key just like "email." Thanks in advance


Solution

  • You could group with the complete data and then get a result for each group.

    const
        results = [{ user_name: 'User 1', email: 'user1@email.com', userid: 'HJ10092', event_type: 'download', country: 'Venezuela', doc_type: 'mspowerpoint', total: '1' }, { user_name: 'User 1', email: 'user1@email.com', userid: 'HJ10092', event_type: 'download', country: 'Venezuela', doc_type: 'document', total: '1' }, { user_name: 'User 1', email: 'user1@email.com', userid: 'HJ10092', event_type: 'download', country: 'Venezuela', doc_type: 'msword', total: '2' }, { user_name: 'User 2', email: 'user2@email.com', userid: 'POG0092', event_type: 'download', country: 'Spain', doc_type: 'png', total: '3' }, { user_name: 'User 2', email: 'user2@email.com', userid: 'POG0092', event_type: 'download', country: 'Spain', doc_type: 'txt', total: '3' }],
        groupedDocs = Object
            .values(Object.groupBy(results, ({ email }) => email))
            .map(group => ({
                email: group[0].email,
                country: group[0].country,
                count: group.map(({ doc_type, total }) => ({ doc_type, total }))
            }));
      
    console.log(groupedDocs);
    .as-console-wrapper { max-height: 100% !important; top: 0; }