0

I need split list in N sublists with balanced size. For example, i have a list with a 101 elements, and max elements allowed in every sublist is 100. The result should be two sublists, one with 50 elements and one with 51 elements. Actually my code is not working correctly for all cases.

    public static void Split()
    {
        List<int> players = new List<int>();

        var totalPlayers = 133;

        for (int i = 0; i < totalPlayers; i++)
        {
            players.Add(i);
        }

        var maxSizeSubList = 100;

        var number = (double)players.Count / maxSizeSubList;
        var numberGroupsRound = Math.Ceiling(number);

        var playersXGroup = (int) Math.Round(players.Count / numberGroupsRound);

        var subLists = SplitList<int>(players, playersXGroup);
    }

    private static List<List<T>> SplitList<T>(List<T> locations, int nSize = 30)
    {
        var list = new List<List<T>>();

        for (int i = 0; i < locations.Count; i += nSize)
        {
            list.Add(locations.GetRange(i, Math.Min(nSize, locations.Count - i)));
        }

        return list;
    }

In this case im getting 3 sublist with, 66, 66 and 1 Result Image

Its dot core 3.1, thanks.

Morelli
  • 5
  • 1
  • 3
  • 1
    Does this answer your question? [Split a collection into \`n\` parts with LINQ?](https://stackoverflow.com/questions/438188/split-a-collection-into-n-parts-with-linq) – gunr2171 May 12 '21 at 13:22
  • I think the issue is when calculating playersXGroup you're using Math.Round. You should change it to Math.Ceiling to make sure that it always rounds up. – J.Loscos May 12 '21 at 13:23
  • There may be something wrong with your algorithm too. For example if I have 21 items and pass in 6 as the size to your second method (because you want four lists back) then you will get three lists of size 6 and one of size three which isn't very balanced. if you want to do it this way I'd advise taking in the number of lists. You can then get the base size as `var baseSize = totalItemCount/numberLists;` (using integer maths to round down. You then do `var biggerListCount = totalItemCount-baseSize*numerLists` and this is how many of your lists will need one extra item to cover the full set. – Chris May 12 '21 at 13:37

1 Answers1

0

Your are rounding off, instead of up:

var playersXGroup = (int)Math.Round(players.Count / numberGroupsRound);

should be

var playersXGroup = (int)Math.Ceiling(players.Count / numberGroupsRound);
bwakabats
  • 603
  • 3
  • 9