【问题标题】:RxJS filter() operatorRxJS filter() 运算符
【发布时间】:2017-04-28 13:03:59
【问题描述】:

我正在尝试找到最干净的解决方案来使用 filter() 运算符来过滤我的 observables。

这里我正在复制服务调用以分别获取femaleList

export class MyComp implements OnInit {

    maleList: IContact[] = [];
    femaleList: IContact[] = [];    

    constructor(private _contactService: ContactService) { }
    ngOnInit() : void {
        this._contactService.getContacts()
         .filter(male => male.gender === 'M')
        subscribe(maleList => this.maleList = maleList);

        this._contactService.getContacts()
         .filter(female => female.gender === 'F')
        subscribe(femaleList => this.femaleList = femaleList);
     } }

联系人列表

 [{
      "id" : 1,
      "name" : "Todd",
      "gender" : "M"
    }, {
      "id" : 2,
      "name" : "Lillian",
      "gender" : "F"
    }]

RxJS 运算符中是否有任何选项可以将单个 observable 分配给两个变量。

如何过滤联系人并将其分配给 maleListfemaleList 使用 RxJS filter() 运算符。

提前致谢

【问题讨论】:

    标签: angular rxjs angular2-services rxjs5 rxjs-dom


    【解决方案1】:

    您不需要过滤器:

    this._contactService.getContacts()
      .subscribe(person => {
        if(person.gender === 'F'){
          this.femaleList.push(person);
        } else {
          this.maleList.push(person);
        }
    

    【讨论】:

    • 我们可以在订阅服务之前过滤数据吗?
    【解决方案2】:

    如果你想使用单个 Observable 并使用两个不同的 Observers 订阅它,你需要使用 share()shareReplay()(在 RxJS 5 中现在只有 .publishReplay().refCount() 可用)(参见 @987654321 @ 和 https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/sharereplay.md)。

    let data = [{
        "id" : 1,
        "name" : "Todd",
        "gender" : "M"
    }, {
        "id" : 2,
        "name" : "Lillian",
        "gender" : "F"
    }];
    
    let maleList = [];
    let femaleList = [];
    
    let source = Observable.defer(() => {
            console.log('Observable.defer');
            return Observable.from(data);
        })
        .publishReplay()
        .refCount();
    
    source
        .filter(male => male.gender === 'M')
        .toArray()
        .subscribe(list => maleList = list);
    
    source
        .filter(male => male.gender === 'F')
        .toArray()
        .subscribe(list => femaleList = list);
    
    console.log('maleList', maleList);
    console.log('femaleList', femaleList);
    

    观看现场演示:https://jsbin.com/hapofu/edit?js,console

    这会打印到控制台:

    Observable.defer
    maleList [ { id: 1, name: 'Todd', gender: 'M' } ]
    femaleList [ { id: 2, name: 'Lillian', gender: 'F' } ]
    

    这两个订阅者共享与source 的相同连接,同时响应被“重播”(如果您在首次发出后订阅,它将重新发送而无需再次订阅source)。

    请注意,来自filter() 的项目一次发出一个。这就是我使用toArray() 收集所有值并将它们作为单个数组重新发送的原因。或者我可以打电话给例如。 maleList.push() 每个值。

    顺便说一句,您还可以使用 partition() 运算符代替 filter() 以避免创建两个订阅。

    【讨论】:

      【解决方案3】:

      你可以使用 lodash:

      .partition(collection, [predicate=.identity]);

      https://lodash.com/docs/#partition

      这会返回 2 个数组,其中一个的值为 false,另一个为 true。只需使用“性别”来建立评估。

      【讨论】:

        猜你喜欢
        • 2021-01-16
        • 2020-11-16
        • 1970-01-01
        • 1970-01-01
        • 2019-01-27
        • 1970-01-01
        • 2016-07-08
        • 1970-01-01
        • 2019-11-07
        相关资源
        最近更新 更多