c# - 如何使用条件窗口而不是基于时间的窗口将整数流拆分为缓冲区?
问题描述
我有一个 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 部分并将流拆分到“无触摸”时刻之间的手指 ID 缓冲区。我也可以这样描述:
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]
解决方案
可能存在一些更好的魔法解决方案,但我想最直接的方法是
private static int[][] GetArrays(int[] intputArray)
{
// use lists for dynamically adding elements
var outputLists = new List<List<int>>();
// initialize with the ignored value
var lastValue = -1;
// iterate over the inputArray
foreach (var value in intputArray)
{
// skip -1 values
if (value < 0)
{
lastValue = -1;
continue;
}
// if a new value begin a new list
if (lastValue != value)
{
outputLists.Add(new List<int>());
}
// add the value to the current (= last) list
outputLists[outputLists.Count - 1].Add(value);
// update the lastValue
lastValue = value;
}
// convert to arrays
// you could as well directly return the List<List<int>> instead
// and access the values exactly the same way
// but since you speak of buffers I guess you wanted arrays explicitely
var outputArrays = new int[outputLists.Count][];
for (var i = 0; i < outputLists.Count; i++)
{
outputArrays[i] = outputLists[i].ToArray();
}
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]
因为您似乎更想动态地一一添加值,所以我根本不会使用数组,而是使用类似的东西
private List<List<int>> arrays = new List<List<int>>();
private int lastValue;
private void AddValue(int value)
{
// skip -1 values
if (value < 0)
{
lastValue = -1;
return;
}
// if a new value begin a new list
if (lastValue != value)
{
arrays.Add(new List<int>());
}
// add the value to the current (= last) list
arrays[outputLists.Count - 1].Add(value);
// update the lastValue
lastValue = value;
}
我的意思是你必须在某个地方存放的东西
推荐阅读
- html - 即使应用了 lang="nl",VoiceOver 也会以系统语言 (en) 读取 aria-live 的内容。如何改变?
- python - 如何在抓取网站过程中自动登录?
- facebook - Facebook graph api获取评论帖子的用户名
- python - 防止 Spacy 分词器拆分特定字符
- mongodb - spring mongo 查询根据匹配条件更新数组元素
- security - 如何在域之间传递 JWT 会话令牌?
- .htaccess - 搜索引擎友好的 URL - .htaccess
- javascript - y 轴在 D3 Charts v4 中设置自定义值
- python - 快速生成numpy数组
- python - 在 Pandas 和 Numpy Python 中保留 Nan 的同时进行值比较的更优雅的方法