是否有任何专用的交互式扩展方法可以在遇到某些条件之前生成最后n个元素?
例如,对于数组src
,我想得到元素99加上它前面的2个元素:
var src = new[] { 1, 2, 3, 4, 99, 5, 6, 7, 99, 8, 9, 10, 99 };
{{3,4,99},{6,7,99},{9,10,99}}
我已经完成了以下代码,但想知道是否有专用的方法或方法组合可以做到这一点。
var result = src.Buffer(3, 1).Where(i => i.Count == 3 && i.Last() == 99);
因此,我对其他解决方案也很好奇,并决定尝试一下。我确实使用窗口技术想出了一个不同的解决方案:
var src = new[] { 1, 2, 3, 4, 99, 5, 6, 7, 99, 8, 9, 10, 99 };
var obs = src.ToObservable().Publish().RefCount();
var windows =
obs
.Zip(
obs.Skip(2).Concat(Observable.Repeat(0, 2)),
(chase, lead) => (chase, lead))
.Publish(pub =>
pub
.Window(
pub.Where(x => x.lead == 99),
_ => pub.Skip(1)));
有了这个解决方案,CCD_ 2现在就是CCD_。大理石图看起来像这样(我希望它有道理,我在犹豫表示可观察到的最佳方式):
src: 1--2--3--4--99--5--6--7--99--8--9--10--99--
WINDOW QUERY
: ------3--4--99-----------------------------
: -------------------6--7--99----------------
: --------------------------------9--10--99--
乍一看,这种行为看起来和你的解决方案一样,但在玩了一番之后,我意识到当你有重叠的寡妇时,它的行为会大不相同。
如果您使用此src
:
// Note the adjacent 99s.
var src = new[] { 1, 2, 3, 4, 99, 99, 6, 7, 99, 8, 9, 10, 99 };
您的解决方案产生:
{{3,4,99},{4,99,99},{6,7,99},{9,10,99}
当窗口化解决方案产生以下结果时:
src: 1--2--3--4--99--99--6--7--99--8--9--10--99--
WINDOW QUERY
: ------3--4--99-----------------------------
: ---------4--99--99-------------------------
: -------------------6--7--99----------------
: --------------------------------9--10--99--
在对两个结果调用SelectMany
之前,似乎没有什么不同。然后你的看起来是这样的:
{3,4,99,4,9,96,7,99,90,10,99}
但是窗口化解决方案交错了可观测值(这是有道理的):
{3,4,9999,6,7,99,10,99}
使用Buffer
解决方案时需要考虑的一件事是,每个缓冲区都需要在返回之前将缓冲区复制到一个新列表中。因此,窗口化解决方案在某些情况下可能会表现得更好。我承认,我不了解可观察器的内部工作原理,就像我不了解枚举器一样,所以我必须做一些测试才能确定。
不管怎样,玩起来很有趣,这可能是一个可行的解决方案,这取决于你的最终目标是什么