【问题标题】:Typescript flatten array with RXJSTypescript 使用 RXJS 展平数组
【发布时间】:2017-03-03 19:59:09
【问题描述】:

Ionic 2 应用程序中的 RXJS 转换问题让我头疼不已。 我想将一个 json 文件扁平化为对象,这是我的简化 json 文件

    [{
     "lingua": "it",
     "labels": {
        "denominazione": "Hi",
     },
     "tipologie": [
      {"denominazione": "test 1"},
      {"denominazione": "test 2"}
    ]
    },...]

这是打字稿代码的sn-p

    export class MyRecord{
       denominazione: string;
       label_denominazione: string;

       constructor(denominazione: string, label_denominazione: string) {
          this.denominazione = denominazione;
          this.label_denominazione = label_denominazione;
       }
    }

    public getRecords() {
       var url = '../assets/records.json'; 
       let records$ = this.http
          .get(url)
          .map(mapRecords);
    return records$;

    function mapRecords(response: Response): MyRecord[] {
       return response.json().filter(x => x.lingua == "it")
        .map(({ lingua, labels, tipologie }) => tipologie.map(tipologia =>
        toMyRecord(labels, tipologia))
       );
    }

    function toMyRecord(l: any, t: any): MyRecord{
      let record= new MyRecord(
        t.denominazione,
        l.denominazione,
      );
      return record;
    }

当我调用服务时:

    members: MyRecord[];
    this.myService.getRecords().subscribe(res => {
        this.members = res;
        },
        err => console.log(err)
    );

我在 this.members 中得到的是一组 MyRecord 数组:

    [[{ label_denominazione: "Hi", denominazione: "test 1"}, { label_denominazione: "Hi", denominazione: "test 2"} ]]

而不是 MyRecord 的数组:

    [{ label_denominazione: "Hi", denominazione: "test 1"}, { label_denominazione: "Hi", denominazione: "test 2"} ]

我尝试使用 flatMap (mergeMap),但出现错误“flatMap 不是函数”(顺便说一句,我已导入运算符 mergeMap)。 我也想知道 this.members 定义为 MyRecord 数组可以接受不同的类型。

【问题讨论】:

    标签: typescript rxjs flatten


    【解决方案1】:

    这里似乎有问题:

    function mapRecords(response: Response): MyRecord[] {
       return response.json().filter(x => x.lingua == "it")
        .map(({ lingua, labels, tipologie }) => tipologie.map(tipologia =>
        toMyRecord(labels, tipologia))
       );
    }
    

    而不是第一个 map 尝试 reduce 这样,它合并映射:

    function mapRecords(response: Response): MyRecord[] {
       return response.json().filter(x => x.lingua == "it")
          .reduce((result, current, idx) => 
              result.concat(current.topologie.map(tipologia =>
                  toMyRecord(current.labels, tipologia)));
          }, []);
    }
    

    它应该做的事情。

    【讨论】:

    • 感谢它就像一个魅力,正如@alebianco 指出的那样,我认为仍然可以使用 Observable 进行操作。
    • 哦,我以为你放弃了flatMap。因此,要继续使用 Observable,我们必须先修复您的设置。对我来说,它适用于import 'rxjs/add/operator/mergeMap';。使用flatMap 粘贴您的尝试,以便我们查看
    • 再想一想,为什么要坚持使用 Observable?对我来说,这看起来像是一次拍摄请求。我会做某事像get().toPromise().then(/*handleResponse*/).catch(/*handleBigNoNo*/)
    • 没关系,您的解决方案工作正常,正如我所说,当我用 flatMap 替换第一个 map 时出现错误,即使我已经添加运营商。我不想坚持使用 Observable,我只是不知道 'response.json()' 返回一个普通对象。再次感谢您启发我。
    【解决方案2】:

    response.json() 返回一个普通对象,而不是可观察对象。从那时起,您将使用标准 Array 方法对简单 Array 进行操作,其中不包括 flatMap

    您可以使用 Observable.from 将其转换为 observable,但根据您在示例中执行的操作,我不认为这样做有什么意义。只需使用不同的策略来映射/减少该数组。

    【讨论】:

      猜你喜欢
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      • 2017-07-17
      • 2017-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多