UniRx: DistinctUntilChanged

Observable.DistinctUntilChanged は同じ値を連続して流さないオペレータです。

f:id:noriok:20180917143151p:plain

using UniRx;
using UniRx.Diagnostics;
using UnityEngine;

public class Main : MonoBehaviour
{
    void Start()
    {
        var s = new[] {1, 2, 3, 2, 2, 2, 5, 5}
            .ToObservable()
            .DistinctUntilChanged();

        s.Debug().Subscribe();
    }
}

実行結果です。

OnSubscribe
OnNext(1)
OnNext(2)
OnNext(3)
OnNext(2)
OnNext(5)
OnCompleted()

OnNext(2) が 2 回出力されていますが、連続する重複値が流れないだけですので、ストリーム全体としては同じ値が複数回ながれることはあります。

IEqualityComparer を指定するサンプル

下のコードは、文字列の大文字と小文字を区別しないで比較するサンプルです。

using System;
using System.Collections.Generic;
using UniRx;
using UniRx.Diagnostics;
using UnityEngine;

public class Main : MonoBehaviour
{
    void Start()
    {
        var s = "abAaBbBb"
            .ToObservable()
            .DistinctUntilChanged(new CharEqualityComparer());

        s.Debug().Subscribe();
    }

    // 大文字小文字を区別せずに比較
    class CharEqualityComparer : IEqualityComparer<char>
    {
        public bool Equals(char a, char b)
        {
            return char.ToLower(a).Equals(char.ToLower(b));
        }

        public int GetHashCode(char obj)
        {
            return char.ToLower(obj).GetHashCode();
        }
    } 
}

実行結果です。

OnSubscribe
OnNext(a)
OnNext(b)
OnNext(A)
OnNext(B)
OnCompleted()

IEqualityComparer の実装方法については、UniRx には UnityEqualityComparer.cs に Vector2 や Color などの EqualityComparer の実装があり参考になります。