为了账号安全,请及时绑定邮箱和手机立即绑定

用它的一次出现替换序列中特定数字的连续出现

用它的一次出现替换序列中特定数字的连续出现

C#
哆啦的时光机 2021-11-14 10:16:21
我无法解决这个特定问题。鉴于序列: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 是如何工作的,因为我无法解释我在这里得到的输出序列。
查看完整描述

3 回答

?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

尝试这个:


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/ Zip/ SelectMany:


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));

甚至更多的选择。



查看完整回答
反对 回复 2021-11-14
?
LEATH

TA贡献1936条经验 获得超6个赞

另一个Zip没有的变体SelectMany:


var observable = new List<int> { 1, 1, 2, 2, 3, 3, 4, 1, 1, 5, 6, 7, 1, 1 }

    .ToObservable();


observable.StartWith(int.MinValue).Zip(observable, (previous, current) => (previous, current))

    .Where(t => t.current != 1 || t.current != t.previous)

    .Select(t => t.current);


查看完整回答
反对 回复 2021-11-14
?
跃然一笑

TA贡献1826条经验 获得超6个赞

如果内置方法不符合您的要求,您始终可以创建自己的方法。


DistinctUntilChanged满足您需求的A相当简单:


public static IEnumerable<T> DistinctUntilChanged<T>(

    this IEnumerable<T> source) 

{

    using (var e = source.GetEnumerator())

    {

        if (!e.MoveNext())

            yield break;


        yield return e.Current;

        var previous = e.Current;


        while (e.MoveNext())

        {

            if (!e.Current.Equals(previous))

            {

                yield return e.Current;

                previous = e.Current;

            }

        }

    }

}


查看完整回答
反对 回复 2021-11-14
  • 3 回答
  • 0 关注
  • 157 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信