オブジェクトのストリームがあり、現在のオブジェクトが前のオブジェクトと同じでないかどうかを比較する必要があります。この場合、新しい値を出力します。私はdistinctUntilChanged演算子が私が望んでいることを正確に実行する必要があることを発見しましたが、何らかの理由で、最初の演算子以外は値を出力しません。私がdistinctUntilChanged値を削除すると、通常どおりに出力されます。
私のコード:
export class SettingsPage {
static get parameters() {
return [[NavController], [UserProvider]];
}
constructor(nav, user) {
this.nav = nav;
this._user = user;
this.typeChangeStream = new Subject();
this.notifications = {};
}
ngOnInit() {
this.typeChangeStream
.map(x => {console.log('value on way to distinct', x); return x;})
.distinctUntilChanged(x => JSON.stringify(x))
.subscribe(settings => {
console.log('typeChangeStream', settings);
this._user.setNotificationSettings(settings);
});
}
toggleType() {
this.typeChangeStream.next({
"sound": true,
"vibrate": false,
"badge": false,
"types": {
"newDeals": true,
"nearDeals": true,
"tematicDeals": false,
"infoWarnings": false,
"expireDeals": true
}
});
}
emitDifferent() {
this.typeChangeStream.next({
"sound": false,
"vibrate": false,
"badge": false,
"types": {
"newDeals": false,
"nearDeals": false,
"tematicDeals": false,
"infoWarnings": false,
"expireDeals": false
}
});
}
}
同じ問題があり、JSON.stringifyを使用してオブジェクトを比較することで修正しました。
.distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b))
汚いが動作するコード。
ようやく問題がどこにあるのかわかりました。 V4以前のバージョンのRxJSに問題があり、V5とはパラメーターの順序が異なります。
RxJS 4:
differentUntilChanged = function(keyFn、comparer)
RxJS 5:
distinctUntilChanged = function(comparer、keyFn)
今日のすべてのドキュメントで、V4パラメータの順序を見つけることができます。これに注意してください!
とにかくアプリケーションにlodashがある場合は、lodashのisEqual()
関数を利用するだけで済みます。この関数は、深い比較を行い、distinctUntilChanged()
のシグネチャと完全に一致します。
.distinctUntilChanged(isEqual),
または、_
利用可能(最近は推奨されません):
.distinctUntilChanged(_.isEqual),
Mehdiのソリューションは高速ですが、順序が維持されないと機能しません。 deep-equal または fast-deep-equal ライブラリのいずれかを使用:
.distinctUntilChanged((a, b) => deepEqual(a, b))
RxJS v6 +以降には、distinctUntilKeyChangedがあります
https://www.learnrxjs.io/operators/filtering/distinctuntilkeychanged.html
const source$ = from([
{ name: 'Brian' },
{ name: 'Joe' },
{ name: 'Joe' },
{ name: 'Sue' }
]);
source$
// custom compare based on name property
.pipe(distinctUntilKeyChanged('name'))
// output: { name: 'Brian }, { name: 'Joe' }, { name: 'Sue' }
.subscribe(console.log);
値を変更可能に変更すると、他の回答はどれも機能しません。変更可能なデータ構造で作業する必要がある場合は、distinctUntilChangedImmutable
を使用できます。値、および比較関数が渡されない場合、以前の値と現在の値が互いに等しいことをアサートします(===アサーションではありません)。