views:

172

answers:

3

I saw this question that asks given a string "smith;rodgers;McCalne" how can you produce a collection. The answer to this was to use String.Split.

If we don't have Split() built in what do you do instead?

Update:

I admit writing a split function is fairly easy. Below is what I would've wrote. Loop through the string using IndexOf and extract using Substring.

string s = "smith;rodgers;McCalne";

string seperator = ";";
int currentPosition = 0;
int lastPosition = 0;

List<string> values = new List<string>();

do
{
    currentPosition = s.IndexOf(seperator, currentPosition + 1);
    if (currentPosition == -1)
        currentPosition = s.Length;

    values.Add(s.Substring(lastPosition, currentPosition - lastPosition));

    lastPosition = currentPosition+1;

} while (currentPosition < s.Length);

I took a peek at SSCLI implementation and its similar to the above except it handles way more use cases and it uses an unsafe method to determine the indexes of the separators before doing the substring extraction.

Others have suggested the following.

  1. An Extension Method that uses an Iterator Block
  2. Regex suggestion (no implementation)
  3. Linq Aggregate method

Is this it?

+1  A: 

Regex?

Or just Substring. This is what Split does internally

Foovanadil
Haha, I think the OP's essentially asking how a split method is implemented.
Dan Tao
+3  A: 

It's reasonably simple to write your own Split equivalent.

Here's a quick example, although in reality you'd probably want to create some overloads for more flexibility. (Well, in reality you'd just use the framework's built-in Split methods!)

string foo = "smith;rodgers;McCalne";
foreach (string bar in foo.Split2(";"))
{
    Console.WriteLine(bar);
}

// ...

public static class StringExtensions
{
    public static IEnumerable<string> Split2(this string source, string delim)
    {
        // argument null checking etc omitted for brevity

        int oldIndex = 0, newIndex;
        while ((newIndex = source.IndexOf(delim, oldIndex)) != -1)
        {
            yield return source.Substring(oldIndex, newIndex - oldIndex);
            oldIndex = newIndex + delim.Length;
        }
        yield return source.Substring(oldIndex);
    }
}
LukeH
+1  A: 

You make your own loop to do the split. Here is one that uses the Aggregate extension method. Not very efficient, as it uses the += operator on the strings, so it should not really be used as anything but an example, but it works:

string names = "smith;rodgers;McCalne";

List<string> split = names.Aggregate(new string[] { string.Empty }.ToList(), (s, c) => {
  if (c == ';') s.Add(string.Empty); else s[s.Count - 1] += c;
  return s;
});
Guffa