Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
237 views
in Technique[技术] by (71.8m points)

c# - Splitting String Arrays into Groups

There is a string [] yield that can contain N count data. I have defined 15 count to be an example.

I want to divide these data into 6 groups.However, I cannot load the last remaining items into the array.

Where am I making a mistake?

string[] tags = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"};

double tagLength = (int)Math.Floor(tags.Length / (double)6);

for (int i = 0; i <= tagLength-1; i++)
{
    string[] groupArrays = new string[6];
    Array.Copy(tags, i * 6, groupArrays, 0, 6);            
}

The output i see

[0] = {1,2,3,4,5,6}

[1] = {7,8,9,10,11,12}


Should be output

[0] = {1,2,3,4,5,6}

[1] = {7,8,9,10,11,12}

[2] = {13,14,15}

question from:https://stackoverflow.com/questions/65951586/splitting-string-arrays-into-groups

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...