tags:

views:

70

answers:

2

Hi all,

here is my problem. I have a list of data, sorted by dateStart :


index    dateStart           dateEnd            value
[0]      2009-11-01 04:20  2009-11-01 05:40   5
[1]      2009-11-01 06:30  2009-11-01 08:42   10
[2]      2009-11-01 07:43  2009-11-01 16:12   0
[3]      2009-11-01 10:43  2009-11-01 14:34   -12
[4]      2009-11-01 12:34  2009-11-01 12:42   3

The final output that I want would be a subset from that list, where dateStart and dateEnd from 2 different items would never clash.

In the current example, I would start at [0] and keep it.
For [1], since its dateStart > [0].dateEnd, I would also keep it.
For [2], since its dateStart <= [1].dateEnd, I would discard it.
For [3], since its dateStart > [2].dateEnd, I would keep it.
For [4], since its dateStart <= [3].dateEnd, I would discard it.

and so on.

I would like to use LINQ (lamda preferred) for that, if possible.
Otherwise, I guess a standard for loop would do the trick.

Another interesting way of getting my final output would be to keep all the data, but add a flag to each item (bValid), that would indicate if the data is to be taken or not.

Thanks! p.s. sorry for Formatting, I tried my best (first post here)

+2  A: 

I think you have an error in one case:

For [3], since its dateStart > [2].dateEnd, I would keep it. 

10:43 > 16:12  --> False

I think this covers what your asking. Though I don't know if you want to check the EndDate of previous discarded items or the last item that was accepted.

        IEnumerable<MyObj> res = l.Where((o,i) => { 
            if (i == 0)
                return true;
            else 
                return o.DateStart > l.ElementAt(i-1).DateEnd;
        });

This only outputs:

0 01-11-2009 4:20:00 01-11-2009 5:40:00 5
1 01-11-2009 6:30:00 01-11-2009 8:42:00 10

because of the early high EndDate 16:12.

(update)

Ok, I saw your comments. This totally changes things. Try this:

    static IEnumerable<MyObj> MyFilter(IEnumerable<MyObj> input)
    {
        MyObj aux = input.First();
        yield return aux;
        foreach (var o in input.Skip(1))
        {
            if (o.DateStart > aux.DateEnd)
            {
                aux = o;
                yield return aux;
            }
        }
    }

It outputs:

0 01-11-2009 4:20:00 01-11-2009 5:40:00 5
1 01-11-2009 6:30:00 01-11-2009 8:42:00 10
3 01-11-2009 10:43:00 01-11-2009 14:34:00 -12
bruno conde
Hi and thanks for your reply!You spotted that correctly, but [3] should be kept, because I forgot to explain another concept in my original question...In fact, I take [3] because its dateStart > [last item that I kept].dateEnd, which is the [1] and its dateEnd is 08:42
ibiza
so it is not always a check on the item before (index - 1), but rather on the last item that I kept...
ibiza
@ibiza, please see my updated answer.
bruno conde
A: 

EXPIRED!!!!

ps