I would suggest changing your code to calculate the number of groups you need to this:
int groups = (count / groupSize);
bool hasPartialGroup = count % groupSize != 0;
if (hasPartialGroup)
{
++groups;
}
The result of the first line will be integer division, so 15 / 6 will result in 2. We then see if there is a remainder using the remainder operator (%
): count % groupSize
. If its result isn't 0, then there is a remainder, and we have a partial group, so we have to account for that.
So for groups = 15
and groupSize = 6
, we'll get count = 3
. For groups = 12
and groupSize = 6
, we'll get count = 2
, etc.
Fixing your code to use this, it might look like:
string[] tags = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"};
int count = tags.Length;
const int groupSize = 6;
int groups = (count / groupSize);
bool hasPartialGroup = count % groupSize != 0;
if (hasPartialGroup)
{
++groups;
}
for (int i = 0; i < groups; i++)
{
// you can't copy beyond the end of the array so we have to choose between the remaining ungrouped items and the group size
int currentGroupSize = Math.Min(tags.Length - i*groupSize, groupSize);
// I'm assuming for a partial group you only want this to be as big as the number of items.
// If you want it to always be 6 then change new string[currentGroupSize] to new string[groupSize] and you should be OK.
string[] groupArrays = new string[currentGroupSize];
Array.Copy(tags, i * groupSize, groupArrays, 0, currentGroupSize);
Console.WriteLine(string.Join(",", groupArrays));
}
Try it online // Example with fixed group size
Alternatively, you could create a batching helper method:
private static IEnumerable<T[]> BatchItems<T>(IEnumerable<T> source, int batchSize)
{
var collection = new List<T>(batchSize);
foreach (var item in source)
{
collection.Add(item);
if (collection.Count == batchSize)
{
yield return collection.ToArray();
collection.Clear();
}
}
if (collection.Count > 0)
{
yield return collection.ToArray();
}
}
This will collect batchSize
number items together and then return one group at a time. You can read about how this works with yield return
here.
Usage:
string[] tags = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"};
List<string[]> batchedTags = BatchItems(tags, 6).ToList();
This will result in 3 string arrays, containing 1,2,3,4,5,6
, 7,8,9,10,11,12
, and 13,14,15
.
You could also make this into an extension method.
Try it online