如何通过JavaScript中的对象键之一对数组进行分组

时间:2019-12-04 08:16:37

标签: javascript

如何使用groupBy对对象进行分组

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}}
]

将其分组为对象键,即PRNPRN1PRN2

输出应为

PRN: [{...}]
PRN1: [{...}]
PRN2: [{...}]

3 个答案:

答案 0 :(得分:4)

您不需要使用RxJS,因为您可以使用内置的Array.reduce函数来做到这一点。

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;
}, {})

结果:

{
  "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
      }
    }
  ]
}

答案 1 :(得分:2)

您可以将 RxJS 与angular一起使用,并以此方式进行操作:

参考: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' ] }

答案 2 :(得分:1)

您可以使用Array.prototype.reduce函数来实现。

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);