2

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;
    }, []);
john
  • 796
  • 1
  • 13
  • 34

4 Answers4

1

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)
IsraGab
  • 4,819
  • 3
  • 27
  • 46
1

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)
sfy
  • 2,810
  • 1
  • 20
  • 22
0

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);
destroyer22719
  • 356
  • 2
  • 6
0

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 
Walter
  • 108
  • 5