Click here to Skip to main content
15,891,473 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Having 2 strings:

1,2,3,4,5,6,7,8,9,10,11,12,13,14 ... 32 and 33,34,35,36,37,38,39,40,41,42 ... 64

I need to merge them alternatively every "n" characters (2,,4,6,8,10 ... 64)

Merge output Every "2" characters: 1,2,33,34,3,4,35,36,5,6 ...
Merge output Every "4" characters: 1,2,3,4,33,34,35,36,5,6,7,8,37,38 ...
Merge output Every "6" characters: 1,2,3,4,5,6,33,34,35,36,37,38,7,8,9,10,11,12,39,40 ...

I tried an approach but it's long and not practical !!!
Is there a better way ?

Thank you

What I have tried:

var SplitWithoutComma1 = JoinedWithComma1.Split(',');
var SplitWithoutComma4 = JoinedWithComma4.Split(',');

        
for (int I = 0; I < SplitWithoutComma1.Length; I += 2)          
//Mix alternatively 2 Elements
{
    MixMerge.AddRange(new[] { SplitWithoutComma1[I + 0],SplitWithoutComma1[I + 1],
                              SplitWithoutComma4[I + 0],SplitWithoutComma4[I + 1]
    });
}


for (int I = 0; I < SplitWithoutComma1.Length; I += 4)          
//Mix alternatively 4 Elements
{
    MixMerge.AddRange(new[] { SplitWithoutComma1[I + 0],SplitWithoutComma1[I + 1],
                              SplitWithoutComma1[I + 2],SplitWithoutComma1[I + 3],

                              SplitWithoutComma4[I + 0],SplitWithoutComma4[I + 1],
                              SplitWithoutComma4[I + 2],SplitWithoutComma4[I + 3]
    });
}


for (int I = 0; I < SplitWithoutComma1.Length; I += 6)          
//Mix alternatively 6 Elements
{
    MixMerge.AddRange(new[] { SplitWithoutComma1[I + 0],SplitWithoutComma1[I + 1],
                              SplitWithoutComma1[I + 2],SplitWithoutComma1[I + 3],
                              SplitWithoutComma1[I + 4],SplitWithoutComma1[I + 5],

                              SplitWithoutComma4[I + 0],SplitWithoutComma4[I + 1],
                              SplitWithoutComma4[I + 2],SplitWithoutComma4[I + 3],
                              SplitWithoutComma4[I + 4],SplitWithoutComma4[I + 5]
    });
}

string JoinedWithComma5 = string.Join(",",MixMerge);
Posted
Updated 20-Mar-22 3:40am
v4

You can improve the solution a lot by refactoring some of the literal code. The biggest problem with literal code is it's inflexible. For example, if the input strings have a different number of elements then this returns an incorrect result or errors. If the strings aren't a multiple of the grouping size 'n' then this returns an incorrect result or errors. You'd also have to hand-code every grouping. Imagine writing out the code for n=256 o_o;

First, let's solve that last problem. We have 'n', let's refactor the code based on that:
C#
for (int I = 0; I < SplitWithoutComma1.Length; I += n)          
{
    for (int j = 0; j < n; j++)
        MixMerge.Add(SplitWithoutComma1[I + j]);
    for (int j = 0; j < n; j++)
        MixMerge.Add(SplitWithoutComma4[I + j]);
}

Now we can do any size 'n'! So let's fix the issue now with strings of different lengths:
C#
int longestString = SplitWithoutComma1.Length;
if (SplitWithoutComma4.Length > longestString)
    longestString = SplitWithoutComma4.Length;

for (int I = 0; I < longestString; I += n)          
{
    if (I < SplitWithoutComma1.Length)
    {
        for (int j = 0; j < n; j++)
            MixMerge.Add(SplitWithoutComma1[I + j]);
    }
    if (I < SplitWithoutComma4.Length)
    {
        for (int j = 0; j < n; j++)
            MixMerge.Add(SplitWithoutComma4[I + j]);
    }
}

So now we use the longest string out of the two for the loop length, and once the shorter one runs out we ignore it. We could also have used the shortest string and then appended what's left of the longer one after the outer loop is finished. Both solutions work.

The last part is fixing what happens if one or both of the strings aren't an exact multiple of n. For example, if we have 2 elements left in one of the arrays and our 'n' is 3, oops! The inner for loop for that array will try to read a 3rd element that doesn't exist. Index out of bounds exception!
C#
int longestString = SplitWithoutComma1.Length;
if (SplitWithoutComma4.Length > longestString)
    longestString = SplitWithoutComma4.Length;

for (int I = 0; I < longestString; I += n)          
{
    if (I < SplitWithoutComma1.Length)
    {
        for (int j = 0; j < n; j++)
        {
            if (I + j < SplitWithoutComma1.Length)
                MixMerge.Add(SplitWithoutComma1[I + j]);
        }
    }
    if (I < SplitWithoutComma4.Length)
    {
        for (int j = 0; j < n; j++)
        {
            if (I + j < SplitWithoutComma4.Length)
                MixMerge.Add(SplitWithoutComma4[I + j]);
        }
    }
}

Now it's looking pretty decent. It can handle any two string arrays and any group size n. Can it still be improved? Yep. It's got a lot of nesting right now and those two if blocks are basically the same code with just a different array. But you know what? It works. And that's a solid start. I'll leave it up to you to improve it further :)
 
Share this answer
 
Comments
Xlance 20-Mar-22 4:12am    
With strings of different lengths, we could do :-)
int Max = Math.Max(SplitWithoutComma1.Length,SplitWithoutComma4.Length);
Jon McKee 20-Mar-22 13:09pm    
:thumbs_up:
Jon beat me to it I see, but here is my solution:
static void Main(string[] args)
{
    string str1 = "1,2,3,4,5,6,7,8,9,10,11,12,13,14";
    string str2 = "33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52";
    MergeArrays(4, str1, str2);
}

static string MergeArrays(int skip, string JoinedWithComma1, string JoinedWithComma4)
{
    var SplitWithoutComma1 = JoinedWithComma1.Split(',');
    var SplitWithoutComma4 = JoinedWithComma4.Split(',');
    List<string> MixMerge = new List<string>();

    for (int i = 0; i < SplitWithoutComma1.Length; i += skip)
    {
        int j = 0;

        while (j < skip && i + j < SplitWithoutComma1.Length)
        {
            MixMerge.Add(SplitWithoutComma1[i + j]);
            j++;
        }

        j = 0;

        while (j < skip && i + j < SplitWithoutComma4.Length)
        {
            MixMerge.Add(SplitWithoutComma4[i + j]);
            j++;
        }
    }

    string JoinedWithComma5 = string.Join(",", MixMerge);
    Debug.Print(JoinedWithComma5);

    return JoinedWithComma5;
}


Using LINQ:
static string MergeArrays(int skip, string JoinedWithComma1, string JoinedWithComma4)
{
    var SplitWithoutComma1 = JoinedWithComma1.Split(',');
    var SplitWithoutComma4 = JoinedWithComma4.Split(',');
    List<string> MixMerge = new List<string>();

    for (int i = 0; i < SplitWithoutComma1.Length; i += skip)
    {
        var takeArr = SplitWithoutComma1.Skip(i).Take(skip);
        MixMerge.AddRange(takeArr);
        takeArr = SplitWithoutComma4.Skip(i).Take(skip);
        MixMerge.AddRange(takeArr);
    }

    string JoinedWithComma5 = string.Join(",", MixMerge);
    Debug.Print(JoinedWithComma5);

    return JoinedWithComma5;
}
 
Share this answer
 
v2

My approach would be to simply use a StringBuilder


C#
static void Main(string[] args)
 {
  string str1 = "abcdefghijkl1234";
  string str2 = "NOPQRSTUVWXYZ";
  StringBuilder builder = new();
  int min = Math.Min(str1.Length, str2.Length);
  int span = 3;
  int i = 0;
  while (i * span <= min - span)
    {
     builder.Append(str1.Substring(i * span, span)).Append(str2.Substring(i * span, span));
     i++;
    }
  Console.WriteLine(builder.ToString());
  Console.ReadLine();
 }
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900