首页 > 解决方案 > 将序列中连续出现的特定数字替换为单个出现

问题描述

我无法解决这个特殊问题。给定顺序:

1  1  2  2  3  3  4  1  1  5  6  7  1  1

我希望将连续出现的 1 替换为单次出现的 1。

1  2  2  3  3  4  1  5  6  7  1

我尝试使用DistinctUntilChanged但没有奏效。

List<int> intList = new List<int>() { 1, 1, 2, 2, 3, 3, 4, 1, 1, 5, 6, 7, 1, 1 };
            IObservable<int> intObsrvr = intList.ToObservable();
            intObsrvr
                .DistinctUntilChanged(x => x == 1)
                .SubscribeConsole();

我得到的输出是:

1,2,1,5,1

我也很好奇这个 keySelector 是如何工作的,因为我无法解释我在这里得到的输出序列。

标签: c#reactive-programmingsystem.reactive

解决方案


尝试这个:

var intList = new List<int>() { 1, 1, 2, 2, 3, 3, 4, 1, 1, 5, 6, 7, 1, 1 };
var intObsrvr = intList.ToObservable();

var query =
    intObsrvr
        .Scan(
            new { skip = false, value = int.MinValue },
            (a, x) =>  new { skip = (a.value == 1) && (x == 1) , value = x })
        .Where(x => !x.skip)
        .Select(x => x.value);

我觉得这.Scan是非常被低估的。


您也可以使用.Publish// ZipSelectMany

var query =
    intObsrvr.Publish(
        xs => xs
            .StartWith(int.MinValue)
            .Zip(xs, (z, x) => z == 1 & x == 1 ? new int[] { } : new [] { x })
            .SelectMany(x => x));

任你选。


var query =
    intObsrvr.Publish(
        xs => xs
            .StartWith(int.MinValue)
            .Zip(xs, (z, x) => z == 1 & x == 1
                ? Observable.Empty<int>()
                : Observable.Return(x))
            .SelectMany(x => x));

更多选择。


推荐阅读