代码之家  ›  专栏  ›  技术社区  ›  NotAgain

将序列中某个数字的连续出现替换为该数字的单个出现

  •  1
  • NotAgain  · 技术社区  · 6 年前

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

    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 回复  |  直到 6 年前
        1
  •  1
  •   Enigmativity    6 年前

    试试这个:

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

    更多选择。

        2
  •  1
  •   Paulo Morgado    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);
    
        3
  •  1
  •   InBetween    6 年前

    如果内置的方法与您的要求不匹配,则始终可以创建自己的方法。

    一个 DistinctUntilChanged 满足您的需求非常简单:

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