T
について特定の条件を満たす要素は重複とみなして除外したReactiveCollection
を作りたいです。以下のコードでは重複を除外したAddress
のコレクションを取得したいと思っています。
いくつか試したのですが、コレクションの変更の通知がうまく行われず0件のままになったりデータが重複したりします。どなたかいい実装方法を教えていただければ幸いです。
c#
1public record Sample(string Id, string Address); 2public class Comp : IEqualityComparer<Sample> 3{ 4 public bool (Sample? x, Sample? y) => x?.Address == y?.Address; 5 public int GetHashCode([DisallowNull] Sample obj) => obj.GetHashCode(); 6} 7 8// 適当なデータ 9// コンストラクタでToReactiveCollectionしたあとにdataの中身が複数件まとめてセットされる 10ObservableCollection<Sample> data; 11 12// ダメな例1 -> Selectの時点でIEnumerable<string>になるためToReadOnlyReactiveCollectionできない 13data.Select(x => x.Address).Distinct().ToReadOnlyReactiveCollection(); 14// ダメな例2 -> Distinctの時点でIEnumerable<Sample>になる 15data.Distinct(new Comp()).ToReadOnlyReactiveCollection(x => x.Address); 16// ダメな例3 -> ToObservableしても変更は通知されない 17data.ToObservable().Select(x => x.Address).Distinct().ToReadOnlyReactiveCollection(); 18// ダメな例4 -> コレクションのAddのたびに走るため件数がおかしくなる 19data.CollectionChangedAsObservable(). 20 SelectMany(_ => data.Select(x => x.Address).Distinct()). 21 ToReadOnlyReactiveCollection();
環境
c# 9.0
これは元のObservableCollectionの削除は考慮する必要があるのでしょうか?
つまり、以下のようなケースの場合、(1)では、ReadOnlyReactiveCollectionは{a, b}となっていますが、(2)では{b,c}としてほしいのでしょうか?それとも{b}でいいのでしょうか?
```
data.Add(new Sample("a", "12"));
data.Add(new Sample("b", "99"));
data.Add(new Sample("c", "12"));
//(1)
data.RemoveAt(0);
//(2)
```
削除は考えていなかったので考慮不要です。
同様に移動(Move)や消去(Reset)、置換(Replace)は考慮しますか?
もし純粋に追加(Add)だけでよければ`ObserveAddChanged()`ですむので、シンプルになります
基本的に毎回洗い替えすることを想定していたので、移動、消去、置換も考慮するつもりはありませんでした。
思ったんですがやはりコレクション操作のそれぞれを購読してフルスキャンしてやるしかないんですかね?ObserveAddChangedだとコレクションに最初にAddするときに100件突っ込むなら100回起きますよね(間違ってたらすみません)。それなら最初にコレクションにデータをつっこむときに重複を除いたObservableCollection<string>を別に作ったほうが効率がいいかなと思ったんですが、どうでしょう。
もしくはObservableCollection<T>でなく、値変更時にPropertyChangedが起きるようにしたT[]のプロパティを作って、要素の増減時は毎回配列を作り直し、そのプロパティからObserveProperty()でReactiveProperty<T[]>や<string>を作ってやるほうがいいのかも・・・
> 毎回洗い替えすることを想定
> コレクション操作のそれぞれを購読してフルスキャンしてやるしかないんですかね?
dataに対する全部の操作でReactiveCollectionを作り直す、ということでしょうか?それだったら、`ReadOnlyReactiveProperty<IReadOnlyList<Sample>>`のほうが適切かもしれませんね。
> ObserveAddChangedだとコレクションに最初にAddするときに100件突っ込むなら100回起きますよね
はい、ただしそれはObservableColletion自体の特性なので、複数まとめての追加を効率よくパフォーマンスよくやりたかったら、ObservableColletionを使用するのを避けねばなりません。
回答1件
あなたの回答
tips
プレビュー