1

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

我想像 (from elmt in Measurement.Datapoints select datapoints.length).SkipWhile(n =>) 但我不知道 lambda 函数如何“向前看”?

4

4 回答 4

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();
于 2013-06-25T14:20:09.933 回答
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;
        }
    }
}
于 2013-06-25T14:08:45.353 回答
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;
        }

    }
}
于 2013-06-25T14:25:59.313 回答
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}。

于 2013-06-25T14:48:17.570 回答