对于非英语母语者来说,这很难搜索,因为我提出的任何搜索词都会产生很多与 OrderBy(降序) 相关的问题,而不是我想要的。
想象我有一个 Thing,这个 Thing 有一个 ThingEvent 对象的集合。现在我想查询事件按特定顺序发生的 Thing 对象。
var result = things.Where(t =>
t.ThingEvents
.Has( te => te.EventType == 1 )
.FollowedBy( te => te.EventType == 2 )
)
.ToList();
这是简单的伪代码,仅用于说明一点。 Thing.ThingEvents 是 IEnumerable 的集合,因此 Has() 和 FollowedBy() 是两个虚构的 LINQ 方法,可帮助我执行以下操作:
最后一部分让我困惑 - 这意味着我们需要 ThingEvents 集合以特定顺序包含 ThingEvents(当我们进行此查询时,该集合已正确排序)。
包含事件类型 [1,2] 的集合将匹配。 [1,1,1,1,2,2,2,2] 和 [1,2,1,2,3,1,2,1,2] 也是如此。但 [2,1,1,1,1,1] 不会匹配 - 因为事件类型 2 的事件类型 1 不会在事件类型 1 之后发生。
使用内置的 LINQ 方法是否可以这样查询?
如果没有,是否可以通过扩展 LINQ 本身来构建这样的东西?在解决这个问题时,我的理解破裂的地方是像Where()这样的方法返回一个简单的布尔值,说明查询的项目是否满足给定的谓词,我想象的Has()和FollowedBy()会做同样的事情,但仍然将它们在列表中的位置的“上下文”传递给以下方法。当然也可以有其他类似的方法(例如 PrecededBy())。
我是否正在尝试执行 LINQ 并非设计用于执行的操作?还是我的做法全错了?或者也许缺少一些非常基本的东西?
感谢您的任何见解!
假设集合可以安全地迭代多次,您可以使用 Zip/Skip 组合来查看对。例如:
var result = things.Where(t =>
t.ThingEvents
.Zip(t.ThingEvents.Skip(1))
.Any(pair => pair.Item1.EventType == 1 && pair.Item2.EventType == 2));
我认为这符合你的要求。当然,如果您需要两个以上的元素,它会变得更加复杂。
如果你经常需要这个,你可能可以构建
Has
/FollowedBy
,但设计至少是不平凡的。 (理想情况下,您应该以仅迭代集合一次的方式执行此操作。)