过滤列表,并增加一个额外的元素

时间:2018-12-11 07:47:52

标签: c# linq

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'->这些是满足(...)条件的项目。

3 个答案:

答案 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
)

Reference

请注意,此过程需要大量资源

答案 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();

(注意:如果您知道它的排序方式,那么TakeWhileWhere更有效率,因为它允许您在结束日期后立即停止枚举。)