是否可以在linq中使用.SkipWhile(n =>(函数)),其中(函数)查看下一行x行?

时间:2013-06-25 13:49:49

标签: c# linq entity-framework linq-to-entities

假设我有一个名为Measurement的实体框架对象。一个测量具有许多DataPoints,每个数据点具有属性Length。假设我想跳过前x个数据点,直到接下来的2个数据点严格增加 例如,如果数据点的长度为{1,1.2,1.1 0.2,1,2,3,4},则列表为{0.2,1,2,3,4}。

我认为(来自Measurement.Datapoints中的elmt选择datapoints.length).SkipWhile(n =>)但我不知道lambdafunction如何“向前看”?

4 个答案:

答案 0 :(得分:0)

如果您能够将整个查询拉入列表,那么它就足够简单了:

var list = data.ToList();

var query = list.SkipWhile((item, index) => index + 2 < list.Count &&
    item < list[index + 1] && list[index + 1] < list[index + 2]);

如果保持延迟执行很重要,那么问题就更难了,你可以用这个函数来做:

public IEnumerable<TSource> NextTwoStrictlyIncreasing<TSource>(IEnumerable<TSource> source,
    Func<TSource, TSource, bool> isStrictlyIncreasing)
{
    using (var iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
            yield break;
        var twoBack = iterator.Current;

        if (!iterator.MoveNext())
            yield break;
        var oneBack = iterator.Current;

        bool previousIsIncreasing = false;
        bool isIncreasing = false;


        while (iterator.MoveNext())
        {
            isIncreasing = isStrictlyIncreasing(oneBack, iterator.Current);
            if (isIncreasing && previousIsIncreasing)
            {
                yield return twoBack;
                yield return oneBack;
                yield return iterator.Current;
                while (iterator.MoveNext())
                    yield return iterator.Current;
                yield break;
            }
            twoBack = oneBack;
            oneBack = iterator.Current;
            previousIsIncreasing = isIncreasing;
        }
    }
}

答案 1 :(得分:0)

var seq = new double[]  {1, 1.2, 1.1, 0.2, 1, 2, 3, 4};

            var state = -1.0;
            var last = 0.0;
            var r = seq.Where(x =>
                                   {
                                       var res = last > x ? state : ++state;
                                       last = x;
                                       return res > 1;
                                   }
                ).ToArray();

var r = seq.SkipWhile(x =>
                                   {
                                       var res = last > x ? state : ++state;
                                       last = x;
                                       return res < 2;
                                   }
                ).ToArray();

答案 2 :(得分:0)

这有点乱,但它可以做你想要的:

IEnumerable<DataPoint> FilterInitialDecreasing(IEnumerable<DataPoint> items)
{
    var buffer = new Queue<DataPoint>();
    int increasingCount = 0;
    int prior = int.MinValue;

    foreach (int data in items.DataPoints)
    {
        switch(increasingCount)
        {

           case 2:
        {
            yield return data;
        }
        else if (data.Length > prior)
        {
           increasingCount++;
           prior = data.Length;
           buffer.EnQueue(data);

           if (increasingCount >2)
           {
               yield return Queue.Dequeue();
               yield return Queue.Dequeue();
               yield return data;
           }
        }
        else
        {
           increasingCount = 0;
           buffer = new Queue<DataPoint>();
           prior = int.MinValue;
        }

    }
}

答案 3 :(得分:0)

完整且通用的解决方案:

class Program
{
    static void Main(string[] args)
    {
        var input = new double[] { 1, 1.2, 1.1, 0.2, 1, 2, 3, 4 };
        var output = input.SkipWhileNext(T => T.IsIncreasing(), 2);

        Console.WriteLine(string.Format("{{ {0} }}", string.Join("; ", output)));
    }
}

public static class Extensions
{
    public static bool IsIncreasing<T>(this IEnumerable<T> e) where T : IComparable<T>
    {
        T last = default(T);
        bool flag = false;

        foreach (T item in e)
        {
            if (flag)
            {
                if (item.CompareTo(last) <= 0)
                {
                    return false;
                }
            }
            else
            {
                flag = true;
            }

            last = item;
        }

        return true;
    }
    public static IEnumerable<T> SkipWhileNext<T>(this IEnumerable<T> e, Func<IEnumerable<T>, bool> predicate, int count)
    {
        count++;
        Queue<T> queue = new Queue<T>(count);

        foreach (T item in e)
        {
            queue.Enqueue(item);

            if (queue.Count == count)
            {
                if (predicate(queue))
                {
                    yield return queue.Dequeue();
                }
                else
                {
                    queue.Dequeue();
                }
            }
        }

        while (queue.Count > 0)
        {
            yield return queue.Dequeue();
        }
    }
}

按预期输出:{0,2; 1; 2; 3; 4}。