如何使用条件窗口而不是基于时间的窗口将整数流分割到缓冲区中?

我有一个 Observable 返回整数,如下所示:


1, 1, 1, 1, -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0

如何将此 Observable 转换为返回这些整数的数组,而不是按基于时间的窗口而是按基于值的窗口拆分流?


这些整数是 Unity Update 事件中 Touch 的 FingerId。对于这项任务来说并不是那么重要,但为了解释为什么我需要它,我必须提供这些详细信息。-1 表示不触摸。这就是差距。我需要删除那些 -1 部分,并将流拆分到“无触摸”时刻之间的 FingerId 缓冲区。我也可以这样描述:


Touch0, Touch0, Touch0, no Touch, no Touch, Touch1

存在整数或其他类型并不重要。只需将流拆分为缓冲区,删除“窗口值”。


这是我的代码,如果有帮助的话:


var leftSideTouchStream = Observable.EveryUpdate()

            .Scan(-1, (id, _) =>

            {

                if (id < 0)

                {

                    var leftSideTouches = Input.touches

                        .Where(t =>

                            t.phase == TouchPhase.Began

                            && t.position.x < Screen.width / 2

                        );


                    return leftSideTouches.Any() ? leftSideTouches.First().fingerId : -1;


                }

                else

                {

                    var touchEnded = Input.touches

                        .Any(t =>

                            t.fingerId == id &&

                            (t.phase == TouchPhase.Ended || t.phase == TouchPhase.Canceled)

                        );


                    return touchEnded ? -1 : id;

                }

            })

            .Select(id =>

            {

                return Input.touches

                    .Where(t => t.fingerId == id)

                    .Select(t => new Nullable<Touch>(t))

                    .FirstOrDefault();

            });

我需要与 Buffer 函数给出的行为完全相同的行为,但正如我所说,根据值而不是时间。如果我有这个流:


1, 1, 1, 1, -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0

并且“窗口值”为-1,则预期结果为:


[1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0]


蓝山帝景
浏览 102回答 2
2回答

MMTTMM

可能存在一些更好的魔法解决方案,但我想最直接的解决方案是这样的private static int[][] GetArrays(int[] intputArray){&nbsp; &nbsp; // use lists for dynamically adding elements&nbsp; &nbsp; var outputLists = new List<List<int>>();&nbsp; &nbsp; // initialize with the ignored value&nbsp; &nbsp; var lastValue = -1;&nbsp; &nbsp; // iterate over the inputArray&nbsp; &nbsp; foreach (var value in intputArray)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // skip -1 values&nbsp; &nbsp; &nbsp; &nbsp; if (value < 0)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lastValue = -1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // if a new value begin a new list&nbsp; &nbsp; &nbsp; &nbsp; if (lastValue != value)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; outputLists.Add(new List<int>());&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // add the value to the current (= last) list&nbsp; &nbsp; &nbsp; &nbsp; outputLists[outputLists.Count - 1].Add(value);&nbsp; &nbsp; &nbsp; &nbsp; // update the lastValue&nbsp; &nbsp; &nbsp; &nbsp; lastValue = value;&nbsp; &nbsp; }&nbsp; &nbsp; // convert to arrays&nbsp; &nbsp; // you could as well directly return the List<List<int>> instead&nbsp; &nbsp; // and access the values exactly the same way&nbsp; &nbsp; // but since you speak of buffers I guess you wanted arrays explicitely&nbsp; &nbsp; var outputArrays = new int[outputLists.Count][];&nbsp; &nbsp; for (var i = 0; i < outputLists.Count; i++)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; outputArrays[i] = outputLists[i].ToArray();&nbsp; &nbsp; }&nbsp; &nbsp; return outputArrays;}如此呼唤var arrays = GetArrays(new int[]{1, 1, 1, 1, -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0});应该导致arrays[0] => [1, 1, 1, 1]arrays[1] => [0, 0, 0, 0]arrays[2] => [0, 0, 0]&nbsp; &nbsp;&nbsp;因为您似乎更想动态地一一添加值,所以我根本不会使用数组,而是使用类似的东西private List<List<int>> arrays = new List<List<int>>();private int lastValue;private void AddValue(int value){&nbsp; &nbsp; // skip -1 values&nbsp; &nbsp; if (value < 0)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; lastValue = -1;&nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; }&nbsp; &nbsp; // if a new value begin a new list&nbsp; &nbsp; if (lastValue != value)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; arrays.Add(new List<int>());&nbsp; &nbsp; }&nbsp; &nbsp; // add the value to the current (= last) list&nbsp; &nbsp; arrays[outputLists.Count - 1].Add(value);&nbsp; &nbsp; // update the lastValue&nbsp; &nbsp; lastValue = value;}我的意思是你必须存储在某个地方的东西

繁星点点滴滴

不幸的是我没有找到任何开箱即用的解决方案,所以我想出了我自己的 Observable 实现:using System;using System.Collections.Generic;using UniRx;public static class ObservableFunctions{&nbsp; &nbsp; public static IObservable<T[]> BufferWhen<T>(this IObservable<T> source, Predicate<T> predicate)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return Observable.Create<T[]>(observer =>&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; List<T> buffer = new List<T>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; source.Subscribe(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; t =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (predicate(t))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buffer.Add(t);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (buffer.Count > 0)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; observer.OnNext(buffer.ToArray());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buffer = new List<T>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; observer.OnError(e);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; () =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; observer.OnCompleted();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Disposable.Empty;&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; }}幸运的是,事情非常简单。比在 Google 中搜索适当的功能更简单...
打开App,查看更多内容
随时随地看视频慕课网APP