1

I have an array List<SomeObject> which contain ascending order of dates (and some more fields with info). The list will be Grouped into a List<List<SomeObject>>, which correlate to my subject.

One List<SomeObject> groups into an List<List<SomeObject>>. In this former case only contain 1 row.

Some calculations occurs on LastOrDefault and FirstOrDefault of that row. (In the end, the method return one SomeObject with a date, type and calculated value).

List<List<SomeObject>> Array; // Should be filled with the grouped List<SomeObject>

List<SomeObject>              // One SomeObject is a row below,
2011-01-01   enumType.Ok        140.0
2011-01-02   enumType.Ok        210.0
2011-01-03   enumType.Ok        250.0
2011-01-04   enumType.Blocking  310.0
2011-01-05   enumType.Ok        4.0
2011-01-06   enumType.Ok        34.0
2011-01-07   enumType.Ok        93.0
and counting..

Each row in the array have a type (enum) which normally are "Ok".
This array can have occurences of "NotOk" instead of "Ok" (simplified description).

So, the question is,
The row 2011-01-05 have NotOk, which must split the array. The result will be as below. All rows up to the Blocking in one array, then next array for the rest of the rows (or to next point of "blocking".

List<SomeObject>
2011-01-01   enumType.Ok        140.0
2011-01-02   enumType.Ok        210.0
2011-01-03   enumType.Ok        250.0
2011-01-04   enumType.Blocking  310.0

List<SomeObject>
2011-01-05   enumType.Ok        4.0
2011-01-06   enumType.Ok        34.0
2011-01-07   enumType.Ok        93.0
and counting..   

Then I can do a separate groupby/calculate sum on each list and lastly sum each groupby together.

[Edit]
I was helped by the answer from BrokenGlass, which worked exactly as stated. Though, I did a typo in my question that change the behavior of his answer. The first item in next array should be AFTER .Blocking. Just take his currentList.Add(item); before the if(currentList.Count - clause and the answer are still correct. Please also mind that this extension should be done only if needed, because we're miss the point of my Q every time it need looping each value because of "Blocking".

Independent
  • 2,924
  • 7
  • 29
  • 45

4 Answers4

2

first I would group the list based on the Enum type "OK","NOT OK".

then do the select based on that type

the below function has already been posted I had used it .

list.GroupBy(item => item.SomeProperty).Select(group => new List<T>(group)) 

have a look at this post for other solutions

Community
  • 1
  • 1
SShebly
  • 2,043
  • 1
  • 21
  • 29
  • Correct me if I'm wrong. Doesn't this put "property X" and "property y" in different arrays, – Independent Nov 03 '11 at 13:30
  • the items with values different in SomeProperty in case its different since you can declare a new list and add .ToList(); at to the end of the expression – SShebly Nov 03 '11 at 13:34
  • Thank's but I still think you understand me wrong. Try the solution from BrokenGlass above on a unittest and see the different of the output. This spared me two hours or three. – Independent Nov 03 '11 at 13:48
2

You could just write a simple extension method to split up your single list into an enumeration of lists, each containing at least one item and split at any item with state NotOk:

public static class MyExtensions
{
    public static IEnumerable<List<SomeClass>> Split(this IEnumerable<SomeClass> source)
    {
        List<SomeClass> currentList = new List<SomeClass>();
        foreach (var item in source)
        {
            if(currentList.Count > 0 && item.State == States.NotOk)
            {
                yield return currentList;
                currentList = new List<SomeClass>();
            }
            currentList.Add(item);
        }

        if (currentList.Count > 0)
            yield return currentList;
    }
}
BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
  • Thank's, that does the trick! Though, I see I should first check for any existing blocks. Avoid run the split at all, if there are null/0. – Independent Nov 03 '11 at 13:45
1
var lstItems = new List<SomeType> { /*Your items in here*/ }

var indexCollection = from item in lstItems
                      where item.EnumIsOkVar == EnumIsOk.NotOk
                      select lstItems.IndexOf(item);

var lstLst = new List<List<SomeType>>();

foreach (var singleIndex in indexCollection) {
   var lstFound = (from item in lst
                  where lstItems.IndexOf(item) >= singleIndex
                  where lstItems.IndexOf(item) < singleIndex + 1
                  select item).ToList();
   lstLst.Add(lstFound);
}
kyjan
  • 291
  • 1
  • 4
  • 11
0

I am having a hard time following your question, but if you are just wanting to split a large list into two sublists based on a property of SomeObject, then you can do the following:

List<SomeObject> list1 = mainList.Where(t => t.NotOk);
List<SomeObject> list2 = mainList.Where(t => !t.NotOk);
landoncz
  • 1,997
  • 14
  • 15