1

How to group the object using groupBy in angular

rowData = [
  {code: "Machine 1", date: "2019-01-19 02:00:00", assets: { PRN: 2}},
  {code: "Machine 2", date: "2019-01-20 00:00:00", assets: { PRN1: 2}},
  {code: "Machine 3", date: "2019-01-21 00:00:00", assets: { PRN: 2}},
  {code: "Machine 4", date: "2019-01-22 00:00:00", assets: { PRN1: 2}},
  {code: "Machine 5", date: "2019-01-23 00:00:00", assets: { PRN2: 2}}
]

group it into Object keys which is the PRN, PRN1, PRN2

the output should be

PRN: [{...}]
PRN1: [{...}]
PRN2: [{...}]
4
  • 2
    There is no groupBy in Angular, only in AngularJs, which is not what the tag in your question is about. Commented Dec 4, 2019 at 8:20
  • 1
    This can be solved in JavaScript/TypeScript and it's not related to Angular. Commented Dec 4, 2019 at 8:21
  • 1
    You can use array#reduce to group your data. Commented Dec 4, 2019 at 8:22
  • 1
    For Angular 2+ can use npmjs.com/package/ngx-pipes#groupby or lodash.com/docs/4.17.15#groupBy Commented Dec 4, 2019 at 8:23

3 Answers 3

4

You don't need to use RxJS because you can do that with the built-in Array.reduce function.

rowData.reduce((groupedBy, row) => {
  // get the PRN/PRN1/PRN2 value
  const key = Object.keys(row.assets)[0];

  // create an array of rows belonging to the key
  // if it does not already exist
  if (!Array.isArray(groupedBy[key])) {
    groupedBy[key] = [];
  }

  // add the current row to the corresponding object key 
  groupedBy[key].push(row);
  return groupedBy;
}, {})

Result:

{
  "PRN": [
    {
      "code": "Machine 1",
      "date": "2019-01-19 02:00:00",
      "assets": {
        "PRN": 2
      }
    },
    {
      "code": "Machine 3",
      "date": "2019-01-21 00:00:00",
      "assets": {
        "PRN": 2
      }
    }
  ],
  "PRN1": [
    {
      "code": "Machine 2",
      "date": "2019-01-20 00:00:00",
      "assets": {
        "PRN1": 2
      }
    },
    {
      "code": "Machine 4",
      "date": "2019-01-22 00:00:00",
      "assets": {
        "PRN1": 2
      }
    }
  ],
  "PRN2": [
    {
      "code": "Machine 5",
      "date": "2019-01-23 00:00:00",
      "assets": {
        "PRN2": 2
      }
    }
  ]
}
Sign up to request clarification or add additional context in comments.

2 Comments

how to make it an array?
for example [0:{PRN:{..}},1{PRN1:{..}}, 2{PRN2:{..}}]
2

You can use RxJS with angular and do it in this way:

Reference: https://rxjs-dev.firebaseapp.com/api/operators/groupBy

import { of } from 'rxjs';
import { groupBy, map, mergeMap, reduce } from 'rxjs/operators';

of(
  { id: 1, name: 'JavaScript' },
  { id: 2, name: 'Parcel' },
  { id: 2, name: 'webpack' },
  { id: 1, name: 'TypeScript' },
  { id: 3, name: 'TSLint' }
)
  .pipe(
    groupBy(p => p.id, p => p.name),
    mergeMap(group$ =>
      group$.pipe(reduce((acc, cur) => [...acc, cur], [`${group$.key}`]))
    ),
    map(arr => ({ id: parseInt(arr[0], 10), values: arr.slice(1) }))
 )
 .subscribe(p => console.log(p));

// displays:
// { id: 1, values: [ 'JavaScript', 'TypeScript' ] }
// { id: 2, values: [ 'Parcel', 'webpack' ] }
// { id: 3, values: [ 'TSLint' ] }

Comments

1

You can achieve is using Array.prototype.reduce function.

let rowData = [
  {code: "Machine 1", date: "2019-01-19 02:00:00", assets: { PRN: 2}},
  {code: "Machine 2", date: "2019-01-20 00:00:00", assets: { PRN1: 2}},
  {code: "Machine 3", date: "2019-01-21 00:00:00", assets: { PRN: 2}},
  {code: "Machine 4", date: "2019-01-22 00:00:00", assets: { PRN1: 2}},
  {code: "Machine 5", date: "2019-01-23 00:00:00", assets: { PRN2: 2}}
]


let ans = rowData.reduce((acc,val)=>{
  let key = Object.keys(val.assets)[0];	
  acc[key] = acc[key] ? acc[key] : [];	
  acc[key].push(val);	
  return acc;

}, {})

console.log(ans);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.