使用 HTTP 响应时如何正确分组数据?

How to groupBy data properly when using HTTP response?

这是我想要实现的目标,我想在数组 JSON 中分组 product_category 但我的数组 JSON 是嵌套的,看起来像这样:

[
    {
        "result": "success",
        "data": [
            {
                "product_id": 17,
                "product_name": "KLO-101",
                "parent_category": "Juicer"
            },
            {
                "product_id": 42,
                "product_name": "CRO-528",
                "parent_category": "Vacuum Cleaner"
            },
            {
                "product_id": 15,
                "product_name": "KLC-127",
                "parent_category": "Juicer"
            },
            {
                "product_id": 41,
                "product_name": "CRO-3120-WD",
                "parent_category": "Vacuum Cleaner"
            }
        ]
    }
]

我要搭建的json是什么,下面是我手写的JSON图解:

[{
    'Vacuum Cleaner' : 
           [{
                "product_id": 41,
                "product_name": "CRO-3120-WD",
                "parent_category": "Vacuum Cleaner"
            },
            {
                "product_id": 42,
                "product_name": "CRO-528",
                "parent_category": "Vacuum Cleaner"
            }],
   'Juicer' : 
            [{
                "product_id": 17,
                "product_name": "KLO-101",
                "parent_category": "Juicer"
                 },
            {
                "product_id": 15,
                "product_name": "KLC-127",
                "parent_category": "Juicer"
            }]
}]

根据我的阅读,在 Whosebug 的某处写到 JSON 数据可以使用我的代码中的 map().groupBy() 进行分组,它看起来像这样:

app.service.ts :

getProductService(): Observable<any> {
    return this.http
        .post(global.server + "/product", this.options)
        .map(a=> a.json().data)
        .groupBy(
            a=>a.parent_category,
            a=>a
        )
        .catch(this.handleError);
}

这是我的 app.component.ts :

  getProduct() {
    this.appService.getProductService().subscribe(
      result => {
        console.log(result);
        this.dataProduct = result[0].data;
      },
      error => this.errorMessage = <any>error
    );
  }

但是我得到一个错误,'a is undefined' 如何正确使用 .groupBy()? angular 我使用的版本是 angular 4

更新!!!

这是我用 martin answer 更新后的代码,但我仍然无法弄清楚,因为我必须从 REST API 中提取 JSON 数据,代码不会'没有检测到 'parent_category',下面是我的代码

app.component.ts

dataProduct : any;

      getProduct() {
        this.appService.getProductService().subscribe(
          result => {
            this.dataProduct = result[0].data;
          },
          error => this.errorMessage = <any>error
        );

        Observable.of(this.dataProduct)
          .mergeMap(array => array) // unpack into single emissionns (or mergeAll() but it's broken in RxJS 5.4)
          .groupBy(item => item.parent_category)
          .mergeMap(observable => observable
            .toArray()
            .map(results => (this.dataProduct = { [results[0].parent_category]: results }))
          )
          .toArray()
          .subscribe(console.log);

          console.log(JSON.stringify(this.dataProduct));
      }

我收到错误

[ts] Property 'parent_category' does not exist on type '{}'

在 angular 1 这就是我的做法

var inputdata = [
{
    "result": "success",
    "data": [
        {
            "product_id": 17,
            "product_name": "KLO-101",
            "parent_category": "Juicer"
        },
        {
            "product_id": 42,
            "product_name": "CRO-528",
            "parent_category": "Vacuum Cleaner"
        },
        {
            "product_id": 15,
            "product_name": "KLC-127",
            "parent_category": "Juicer"
        },
        {
            "product_id": 41,
            "product_name": "CRO-3120-WD",
            "parent_category": "Vacuum Cleaner"
        }
    ]
}];

var grouped = _(inputdata[0].data).groupBy(function (d) {
    return d.parent_category;
});

var finalArray = _.mapObject(grouped, function (value, key) {
    return value;
});

groupBy 是一个发出 Observables 的 RxJS 运算符。换句话说,它 returns 一个 Observable 发出其他 Observable(所谓的 "higher-order Observable")。只使用 map() 并在那里转换数据会更容易,但是如果你想使用 groupBy 你需要做一些调整以确保内部 Observable 在你将它传递给之前完成结果对象:

const data = [
    {
        "product_id": 17,
        "product_name": "KLO-101",
        "parent_category": "Juicer"
    },
    {
        "product_id": 42,
        "product_name": "CRO-528",
        "parent_category": "Vacuum Cleaner"
    },
    {
        "product_id": 15,
        "product_name": "KLC-127",
        "parent_category": "Juicer"
    },
    {
        "product_id": 41,
        "product_name": "CRO-3120-WD",
        "parent_category": "Vacuum Cleaner"
    }
];

Observable.of(data)
    .mergeMap(array => array) // unpack into single emissionns (or mergeAll() but it's broken in RxJS 5.4)
    .groupBy(item => item.parent_category)
    .mergeMap(observable => observable
        .toArray()
        .map(results => ({ [results[0].parent_category] : results }))
    )
    .toArray()
    .subscribe(console.log);

打印:

[ { Juicer: [ { product_id: 17,
       product_name: 'KLO-101',
       parent_category: 'Juicer' },
     { product_id: 15,
       product_name: 'KLC-127',
       parent_category: 'Juicer' } ] },
  { 'Vacuum Cleaner': [ { product_id: 42,
       product_name: 'CRO-528',
       parent_category: 'Vacuum Cleaner' },
     { product_id: 41,
       product_name: 'CRO-3120-WD',
       parent_category: 'Vacuum Cleaner' } ] 
} ]

我认为我必须实现 lodash,因为我对 observable 方式很困惑,我真的无法理解它,所以我决定使用 lodash 方式,它非常简单,所以这是我的代码如何将 JSON数据正常。我必须导入已经包含在我的项目中的 lodash,如果你的 node_modules 中没有 lodash,你必须 npm install 它

import * as _ from 'lodash';

  getProduct() {
    this.appService.getProductService().subscribe(
      result => {
        this.dataTest = result;

        let datas = this.dataTest;

        this.dataProduct = _(datas)
        .groupBy(data => data.parent_category)
        .map((datas, category) => ({ category, datas }))
        .value();

      },
      error => this.errorMessage = <any>error
    );

我只需要在 "datas" 中使用 *ngFor 在 HTML

中循环 JSON 数据