Search code examples
algorithmlanguage-agnosticstring

Join a string using delimiters


What is the best way to join a list of strings into a combined delimited string. I'm mainly concerned about when to stop adding the delimiter. I'll use C# for my examples but I would like this to be language agnostic.

EDIT: I have not used StringBuilder to make the code slightly simpler.

Use a For Loop

for(int i=0; i < list.Length; i++)
{
    result += list[i];
    if(i != list.Length - 1)
        result += delimiter;
}

Use a For Loop setting the first item previously

result = list[0];
for(int i = 1; i < list.Length; i++)
    result += delimiter + list[i];

These won't work for an IEnumerable where you don't know the length of the list beforehand so

Using a foreach loop

bool first = true;
foreach(string item in list)
{
    if(!first)
        result += delimiter;
    result += item;
    first = false;
}

Variation on a foreach loop

From Jon's solution

StringBuilder builder = new StringBuilder();
string delimiter = "";
foreach (string item in list)
{
    builder.Append(delimiter);
    builder.Append(item);
    delimiter = ",";       
}
return builder.ToString();

Using an Iterator

Again from Jon

using (IEnumerator<string> iterator = list.GetEnumerator())
{
    if (!iterator.MoveNext())
        return "";
    StringBuilder builder = new StringBuilder(iterator.Current);
    while (iterator.MoveNext())
    {
        builder.Append(delimiter);
        builder.Append(iterator.Current);
    }
    return builder.ToString();
}

What other algorithms are there?


Solution

  • It's impossible to give a truly language-agnostic answer here as different languages and platforms handle strings differently, and provide different levels of built-in support for joining lists of strings. You could take pretty much identical code in two different languages, and it would be great in one and awful in another.

    In C#, you could use:

    StringBuilder builder = new StringBuilder();
    string delimiter = "";
    foreach (string item in list)
    {
        builder.Append(delimiter);
        builder.Append(item);
        delimiter = ",";       
    }
    return builder.ToString();
    

    This will prepend a comma on all but the first item. Similar code would be good in Java too.

    EDIT: Here's an alternative, a bit like Ian's later answer but working on a general IEnumerable<string>.

    // Change to IEnumerator for the non-generic IEnumerable
    using (IEnumerator<string> iterator = list.GetEnumerator())
    {
        if (!iterator.MoveNext())
        {
            return "";
        }
        StringBuilder builder = new StringBuilder(iterator.Current);
        while (iterator.MoveNext())
        {
            builder.Append(delimiter);
            builder.Append(iterator.Current);
        }
        return builder.ToString();
    }
    

    EDIT nearly 5 years after the original answer...

    In .NET 4, string.Join was overloaded pretty significantly. There's an overload taking IEnumerable<T> which automatically calls ToString, and there's an overload for IEnumerable<string>. So you don't need the code above any more... for .NET, anyway.