0

I'm trying to solve the following problem, I have a Collection that contain some data:

+-------------+---------------+-------------+
|     Date    |  InitialValue |  FinalValue |
+-------------+---------------+-------------+
|  21.05.2003 | 0             | 382087.14   |
|  23.06.2003 | 408206.52     | 110622.79   |
|  19.07.2004 | 123811.34     | 0           |
|  31.12.2011 | 0             | 0           |
|  08.06.2012 | 0             | 501854.71   |
|  31.12.2012 | 501854.71     | 546208.19   |
|  31.12.2013 | 634535.58     | 666284.47   |
|  30.06.2014 | 666284.47     | 725837.32   |
|  08.07.2014 | 725837.32     | 729646.48   |
+-------------+---------------+-------------+

What I need to do is to split this list into multiple lists when the final value is equal to 0. The expected result should be something like this:

Result list 1

+-------------+---------------+-------------+
|     Date    |  InitialValue |  FinalValue |
+-------------+---------------+-------------+
|  21.05.2003 | 0             | 382087.14   |
|  23.06.2003 | 408206.52     | 110622.79   |
|  19.07.2004 | 123811.34     | 0           |
+-------------+---------------+-------------+

Result list 2

+-------------+---------------+-------------+
|     Date    |  InitialValue |  FinalValue |
+-------------+---------------+-------------+
|  31.12.2011 |             0 |           0 |
+-------------+---------------+-------------+

Result list 3

+-------------+---------------+-------------+
|     Date    |  InitialValue |  FinalValue |
+-------------+---------------+-------------+
|  08.06.2012 | 0             | 501854.71   |
|  31.12.2012 | 501854.71     | 546208.19   |
|  31.12.2013 | 634535.58     | 666284.47   |
|  30.06.2014 | 666284.47     | 725837.32   |
|  08.07.2014 | 725837.32     | 729646.48   |
+-------------+---------------+-------------+

Can somebody give me an elegant way to solve my problem?

Raphael
  • 1,677
  • 1
  • 15
  • 23
  • 3
    Have you done anything to try to solve this on your own? – Rawling Jul 09 '14 at 13:09
  • I've tried to use takewhile, but this solve just the first split. I thought about using groupby, but i could not figure out how to group the set of data in the right way – Raphael Jul 09 '14 at 13:12
  • 4
    This is a near-duplicate of http://stackoverflow.com/q/22847802/1549380. – Zack Butcher Jul 09 '14 at 13:14
  • Zack thank you! I have typed the right search, that is what I was looking for! Sorry for the duplicate – Raphael Jul 09 '14 at 13:18
  • 2
    @Zack Ah, the one line linq solution. Seems to be doing the same as my code but with an aggregate, interesting. Although to be honest, I'd stick with a for loop for easier readability. – Carra Jul 09 '14 at 13:41
  • @Carra In production code I probably would as well - that question asked specifically for a LINQ solution, however. It shouldn't be hard to translate that to a loop though, simply replace the Aggregate with `foreach` and declare the required variables (mostly just the `List>`) outside the loop (which is exactly what your answer does). – Zack Butcher Jul 09 '14 at 13:52

3 Answers3

4

You don't always need linq:

var List<Data> myData;
var List<List<Data>> mySplittedData;

mySplittedData.Add(new List<Data>());
foreach(var item in myData)
{
  mySplittedData.Last().Add(item);
  if(item.FinalValue == 0)
    mySplittedData.Add(new List<Data>());
}

Should work although I'm sure someone will come up with a clever one line linq solution :)

Carra
  • 17,808
  • 7
  • 62
  • 75
1

I'm not sure if this is elegant, but it uses Linq all the same:

var result = items.Aggregate(new List<List<Item>> { new List<Item>() }, (list, value) =>
{
    list.Last().Add(value);
    if (value.FinalValue == 0)
    {
        list.Add(new List<Item>());
    }
    return list;
});
Bas
  • 26,772
  • 8
  • 53
  • 86
0

Psuedo code

while (more result) {
  list = input.Skip(n).TakeWhile(not 0)
  n += list.Count()
  use or store list
}

Not the most elegant, as the skip will have to skip over the first element of input many times, but might get you started.

Jonny
  • 2,509
  • 23
  • 42