RxJS filter() 运算符

RxJS filter() operator

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

在这里,我正在复制服务调用以单独获得 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 运算符中是否有任何选项可以将单个可观察值分配给两个变量。

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

提前致谢

您不需要过滤器:

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

如果你想使用单个 Observable 并用两个不同的观察者订阅它,你需要使用 share()shareReplay()(在 RxJS 5 中现在仅适用于 .publishReplay().refCount())(参见 https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/publish.md and 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 的相同连接,同时响应是 "replayed"(如果您在它首次发出后订阅,它将重新发出而无需订阅 source 再次)。

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

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

你可以使用 lodash:

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

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

这 returns 2 个数组,其中一个的值评估为 false,另一个为 true。只需使用 'gender' 来构建评估。