0

Problem: spending too much time solving simple problems. Oh, here's the simple problem.

  • Input: string inStr, char delimiter
  • Output: string[] outStrs where string.Join("", outStrs) == inStr and each item in outStrs before the last item must end with the delimiter. If inStr ends with the delimiter, then the last item in outStrs ends with the delimiter as well.

Example 1:

  • Input: "my,string,separated,by,commas", ','
  • Output: ["my,", "string,", "separated,", "by,", "commas"]

Example 2:

  • Input: "my,string,separated,by,commas,", ','
  • Output: ["my,", "string,", "separated,", "by,", "commas,"] (notice trailing comma)

Solution with Regex: here

I want to avoid using Regex, simply because this requires only character comparison. It's algorithmically just as complex to do as what string.Split() does. It bothers me that I cannot find a more succinct way to do what I want.

My bad solution, which doesn't work for me... it should be faster and more succinct.

var outStr = inStr.Split(new[]{delimiter}, 
                         StringSplitOptions.RemoveEmptyEntries)
                  .Select(x => x + delimiter).ToArray();
if (inStr.Last() != delimiter) {
    var lastOutStr = outStr.Last();
    outStr[outStr.Length-1] = lastOutStr.Substring(0, lastOutStr.Length-1);
}
Frank Bryce
  • 8,076
  • 4
  • 38
  • 56
  • @James I don't need to use the power of regular expressions. It's a simple character comparison. It feels like too big of a tool. This problem isn't any harder than the `string.Split()` method, the functionality just needs to be slightly different. – Frank Bryce Jan 18 '16 at 17:01
  • [Many](https://www.google.ch/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=c%23+string+split+keep+delimiter) solved that with Regex. Is there any chance in appending the delimiter when you are using the values? something like: `foreach(string token in outStrs) { string value = token + delimiter; }` ? –  Jan 18 '16 at 17:01

3 Answers3

2

Using LINQ:

string input = "my,string,separated,by,commas";
string[] groups = input.Split(',');
string[] output = groups
    .Select((x, idx) => x + (idx < groups.Length - 1 ? "," : string.Empty))
    .Where(x => x != "")
    .ToArray();

Split the string into groups, then transform every group that is not the last element by appending a comma to it.

Just thought of another way you could do it, but I don't think this method is as clear:

string[] output = (input + ',').Split( new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
    .Select(x => x + ',').ToArray();
Frank Bryce
  • 8,076
  • 4
  • 38
  • 56
TVOHM
  • 2,740
  • 1
  • 19
  • 29
0

Seems pretty simple to me without using Regex:

string inStr = "dasdasdas";
char delimiter = 'A';
string[] result = inStr.Split(new string[] { inStr }, System.StringSplitOptions.RemoveEmptyEntries);
string lastItem = result[result.Length - 1];
int amountOfLoops = lastItem[lastItem.Length - 1] == delimiter ? result.Length - 1 : result.Length - 2;
for (int i = 0; i < amountOfLoops; i++)
{
    result[i] += delimiter;
}
Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
0
public static IEnumerable<string> SplitAndKeep(this string s, string[] delims)
    {
        int start = 0, index;
        string selectedSeperator = null;
        while ((index = s.IndexOfAny(delims, start, out selectedSeperator)) != -1)
        {
            if (selectedSeperator == null)
                continue;
            if (index - start > 0)
                yield return s.Substring(start, index - start);
            yield return s.Substring(index, selectedSeperator.Length);
            start = index + selectedSeperator.Length;
        }

        if (start < s.Length)
        {
            yield return s.Substring(start);
        }
    }