class xyz
{
DateTime TimeStamp;
String a;
}
我有一个列表,我需要使用where子句对其进行过滤,但还需要一个上一个元素。例子
listVariable.OrderBy(x=>x.TimeStamp).Where(x => x.Timestamp >=
StartDateTime.LocalDateTime && x.Timestamp <
EndDateTime.LocalDateTime).ToList();
我需要满足上述条件的物品,并且我还需要再增加一个先前的元素(即,在满足此条件之前的元素 x => x.Timestamp> = StartDateTime.LocalDateTime)。我该如何实现?
例如:该列表包含类似
'09 / 11/2018'
'2018/11/10'
'15 / 11/2018'
'2018/11/18'
'21 / 11/2018'
'25 / 11/2018'
,如果我查询18-20之间的日期。我应该得到 '15 / 11/2018'->前一个额外元素 '18 / 11/2018''20 / 11/2018'->这些是满足(...)条件的项目。
答案 0 :(得分:2)
您可以创建两个集合,然后将它们合并:
var list1 = listVariable.OrderBy(x=>x.TimeStamp).Where(x => x.Timestamp >=
StartDateTime.LocalDateTime && x.Timestamp <
EndDateTime.LocalDateTime).ToList();
var minItem = list1.Min(x=>x.TimeStamp);
var list2 = listVariable.Where(x.Timestamp < minItem.LocalDateTime).OrderBy(x=>x.TimeStamp).First();
var finalList = list.Concat(list2);
答案 1 :(得分:0)
您可以使用MoreLinq库
它具有Lead和Lag功能。
public static IEnumerable<TResult> Lag<TSource, TResult>(
this IEnumerable<TSource> source,
int offset,
TSource defaultLagValue,
Func<TSource, TSource, TResult> resultSelector
)
请注意,此过程需要大量资源
答案 2 :(得分:0)
在这种情况下,我编写了自己的简单扩展方法(因为它很有趣,并且减少了对外部库的依赖)。
public static class MyExtensions
{
public static IEnumerable<T> SkipButOneWhile<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
using (var e = source.GetEnumerator())
{
var hasLeading = false;
var leading = default(T);
T current;
while (true)
{
if (!e.MoveNext()) yield break;
current = e.Current;
if (predicate(current))
{
hasLeading = true;
leading = current;
}
else
break;
}
if (hasLeading)
yield return leading;
yield return current;
while (e.MoveNext())
yield return e.Current;
}
}
}
示例:
listVariable
.OrderBy(x => x.TimeStamp)
.SkipButOneWhile(x => x.TimeStamp < start)
.TakeWhile(x => x.TimeStamp < end)
.ToList();
(注意:如果您知道它的排序方式,那么TakeWhile
比Where
更有效率,因为它允许您在结束日期后立即停止枚举。)