是否可以使用LINQ来查询按特定顺序出现的元素?

问题描述 投票:0回答:1

对于非英语母语者来说,这很难搜索,因为我提出的任何搜索词都会产生很多与 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 方法,可帮助我执行以下操作:

  1. 验证给定谓词是否为真 - 在这方面它们与Where() LINQ方法相同。
  2. 在 FollowedBy 的情况下,这种情况发生在序列中的前一个“匹配”之后。

最后一部分让我困惑 - 这意味着我们需要 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 并非设计用于执行的操作?还是我的做法全错了?或者也许缺少一些非常基本的东西?

感谢您的任何见解!

c# linq
1个回答
0
投票

假设集合可以安全地迭代多次,您可以使用 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
,但设计至少是不平凡的。 (理想情况下,您应该以仅迭代集合一次的方式执行此操作。)

© www.soinside.com 2019 - 2024. All rights reserved.