john
john

Reputation: 834

How can i group objects of array to get the desired data format?

im trying to group my data of objects using this array of objects:

var data = [ 
    { IdUser: 8, Name: "John Smith", transferType: 'download', total: 6 },
    { IdUser: 12, Name: "Jane Smith", transferType: 'download', total: 15 },
    { IdUser: 11, Name: "Joe Smith", transferType: 'download', total: 20 },
    { IdUser: 12, Name: "Jane Smith", transferType: 'upload', total: 7 },
    { IdUser: 11, Name: "Joe Smith", transferType: 'upload', total: 16 },
    { IdUser: 8, Name: "John Smith", transferType: 'upload', total: 12 }
 ];

to get this desired output format of all objects into new array:

  [
    {
       IdUser: 8,
       Name: 'John Smith',
       download: [{ IdUser: 8, Name: "John Smith", transferType: 'download', total: 6}],
       upload: [{ IdUser: 8, Name: "John Smith", transferType: 'upload', total: 12 }]
    },
    { 
       IdUser: 12,
       Name: 'Jane Smith',
       donwload: [{ IdUser: 12, Name: "Jane Smith", transferType: 'download', total: 15 }],
       upload: [{ IdUser: 12, Name: "Jane Smith", transferType: 'upload', total: 7 }]
    },
    {
       IdUser: 11,
       Name: 'Joe Smith',
       download: [{ IdUser: 11, Name: "Joe Smith", transferType: 'download', total: 20 }],
       upload: [{ IdUser: 11, Name: "Joe Smith", transferType: 'upload', total: 16 }]
    }
  ];

I have tried to use reduce function but its not the desired format that im getting:

data.reduce(function (a, b) {
      a[b.Name] = a[b.Name] || [];   
      a[b.Name]["IdUser"] = b.IdUser;  
      a[b.Name][b.transferType] = a[b.Name][b.transferType] || [];     
      a[b.Name][b.transferType].push(b);
      return a;
    }, []);

Upvotes: 2

Views: 51

Answers (4)

sfy
sfy

Reputation: 3238

Edited to use reduce.

var data = [{
    IdUser: 8,
    Name: "John Smith",
    transferType: 'download',
    total: 6
  },
  {
    IdUser: 12,
    Name: "Jane Smith",
    transferType: 'download',
    total: 15
  },
  {
    IdUser: 11,
    Name: "Joe Smith",
    transferType: 'download',
    total: 20
  },
  {
    IdUser: 12,
    Name: "Jane Smith",
    transferType: 'upload',
    total: 7
  },
  {
    IdUser: 11,
    Name: "Joe Smith",
    transferType: 'upload',
    total: 16
  },
  {
    IdUser: 8,
    Name: "John Smith",
    transferType: 'upload',
    total: 12
  }
];

let ret = data.reduce((ret, cur) => {
  let computed = ret.find(record => cur.IdUser === record.IdUser)
  if (computed) {
    computed[cur.transferType].push(cur)
  } else {
    let fresh = {
      IdUser: cur.IdUser,
      Name: cur.Name,
      download: [],
      upload: []
    }
    fresh[cur.transferType].push(cur)
    ret.push(fresh)
  }
  return ret
}, [])

console.log(ret)

Upvotes: 1

IsraGab
IsraGab

Reputation: 5185

I would suggest you to do it in 2 times.

First time use a group function to group data by IdUser.

Then use a for in loop:

var data = [
  {
    "IdUser": 8,
    "Name": "John Smith",
    "transferType": "download",
    "total": 6
  },
  {
    "IdUser": 12,
    "Name": "Jane Smith",
    "transferType": "download",
    "total": 15
  },
  {
    "IdUser": 11,
    "Name": "Joe Smith",
    "transferType": "downloaded",
    "total": 20
  },
  {
    "IdUser": 12,
    "Name": "Jane Smith",
    "transferType": "upload",
    "total": 7
  },
  {
    "IdUser": 11,
    "Name": "Joe Smith",
    "transferType": "upload",
    "total": 16
  },
  {
    "IdUser": 8,
    "Name": "John Smith",
    "transferType": "upload",
    "total": 12
  }
];

var groupBy = function(xs, key) {
  return xs.reduce(function(rv, x) {
    (rv[x[key]] = rv[x[key]] || []).push(x);
    return rv;
  }, {});
};
var tmp =  groupBy(data, 'IdUser');

var formattedData = [];
for(var id in tmp ){
    formattedData.push({
    "IdUser": id,
    "Name": tmp[id][0].Name,
    "download": tmp[id].filter(obj => obj.transferType == "download"),
    "upload":tmp[id].filter(obj => obj.transferType == "upload")
    })
}
console.log(formattedData)

Upvotes: 1

Walter
Walter

Reputation: 128

You can use a simple loop like:

for (let i=0; i<data.length; i++) { ... }

Inside the loop you can access each object and property like:

data[i].IdUser 

Upvotes: 0

destroyer22719
destroyer22719

Reputation: 404

You can use the array.map method.

const myObj = [
    {
       IdUser: 8,
       Name: 'John Smith',
       download: [{ IdUser: 8, Name: "John Smith", transferType: 'download', total: 6}],
       upload: [{ IdUser: 8, Name: "John Smith", transferType: 'upload', total: 12 }]
    },
    { 
       IdUser: 12,
       Name: 'Jane Smith',
       donwload: [{ IdUser: 12, Name: "Jane Smith", transferType: 'download', total: 15 }],
       upload: [{ IdUser: 12, Name: "Jane Smith", transferType: 'upload', total: 7 }]
    },
    {
       IdUser: 11,
       Name: 'Joe Smith',
       download: [{ IdUser: 11, Name: "Joe Smith", transferType: 'downloaded', total: 20 }],
       upload: [{ IdUser: 11, Name: "Joe Smith", transferType: 'upload', total: 16 }]
    }
  ];

const uploadData = myObject.map(val => val.upload);
const downloadData = myObject.map(val => val.download);
const newData = uploadData.concat(downloadData);

Upvotes: 0

Related Questions