Simon Price
Simon Price

Reputation: 3261

Split one list into multiple lists by divisible number

I am working on a dynamic solution where I need to split one big list into x number of lists based on a variable that is passed in.

Because the classes I am working with are quite complex, in order get a minimal replicable problem I have crated the below code that represents my issue 100%.

The issues that I am facing are a Divide by 0 issue with the below code.

Other issues faced when I change if (j % i == 0) to if (j % 3 == 0) I get results of "1", "4", "7".

And when I look at removing an item from the list in the if block with the change above i get

3 new lists, and 3 items remaining in the original list.

1, 5, 9

2, 7,

3

4, 6, 8

void Main()
{
var listsToSplit = 3;

var l = new List<string>(){
    "1", "2", "3", "4", "5", "6", "7", "8",
    "9"
};

var dict = new Dictionary<int, List<string>>();

for (var i = 0; i < listsToSplit; i++)
{
    for (var j = 0; j < l.Count; j++)
    {
        if (j % i == 0)
        {
            List<string> value;

            if (dict.TryGetValue(i, out value))
            {
                value.Add(l[j]);
            }
            else
            {
                var newListItem = new List<string> {l[j]};
                dict.Add(i, newListItem);
            }
        }

    }
}

}

Ideally what I am after out of this is 3 lists, of

1, 4, 7

2, 5, 8

3, 6, 9

and then i'll need to mop up any remaining items after say if I have a 10 and 11.

I have looked at

Split List<string> into multiple lists

and

Split List into Sublists with LINQ

which are close to what I need, but they are not complete solutions for what I need and therefore I do not believe this is a duplicate of my issue, and would appreciate all the help possible.

Thanks

Simon

Upvotes: 0

Views: 777

Answers (1)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186803

If I've understood you right, you want to split the initial list into, say, 3 groups by items indexes modulo 3:

  1. 1st group - 0th, 3d, 6th, ... 3N th item ...
  2. 2nd group - 1st, 4th, 7th, ... 3N + 1 th item ...
  3. 3d group - 2nd 5th, 8th, ... 3N + 2 th item ...

you can try grouping them by with a help of Linq:

  List<List<string>> result = l
    .Select((value, index) => new {
      value,
      index
    })
   .GroupBy(item => item.index % listsToSplit, item => item.value)
   .Select(chunk => chunk.ToList())
   .ToList();

Or if you want a dictionary as a result:

  var dict = l
    .Select((value, index) => new {
      value,
      index
    })
    .GroupBy(item => item.index % listsToSplit, item => item.value)
    .ToDictionary(chunk => chunk.Key, chunk => chunk.ToList());

Upvotes: 7

Related Questions