Condividi tramite


Concatenating A List of Elements into A String, From [A] [B] [C] into "A, B, C"

This is a quite common problem, there is a list of strings, and you need to concatenate them with a delimiter, let says a comma. There are several different approaches to this problem.

Before .Net era, I use for loop, and check if the loop counter is not pointing to the last element in the list. If it is not pointing to the last element, add the delimiter. This approach has one problem, if the number of elements are not known. The other way is by concatenating the list and the delimiter, and then truncate the last delimiter after assembling the whole list.

After .Net becoming more popular, the framework utilizes iterator pattern. Using foreach is much more convenient way to iterate and also to concatenate a list. The solution I had before is much more problematic, as I do not know if I am reading at the last element.

Currently, I have two favorite methods to concatenate a list of elements into a single string with delimiter in between.

The first one is using LINQ.

 public string Concatenate(IEnumerable<string> list, string delimiter)
{
    return list.Aggregate((First, Second) => First + delimiter + Second);
}

That method above, probably does not have the greatest performance, as it will create too many strings, especially if the list has a lot of elements. The second one is using extension method, this code has better performance.

 public static class ConcatExtension
{
    public static string Concatenate<T>(this IEnumerable<T> list, string delimiter) 
    {
        StringBuilder Builder = new StringBuilder();
        
        using (IEnumerator<T> Reader = list.GetEnumerator())
        {
            if (Reader.MoveNext()) Builder.Append(Reader.Current.ToString());
            while (Reader.MoveNext()) Builder.Append(delimiter).Append(Reader.Current.ToString());
        }

        return Builder.ToString();
    }
}

Now let see, the second approach uses StringBuilder, thus reducing the memory pressure. The idea is not to add delimiter after processing the element, but to add the delimiter before every element, except the first one.

If I have these array of values:

 List<string> ListOfValues = new List<string>()  { "Orange", "Apple", "Watermelon", "Grape", "Peach", "Banana" };

Then these two calls will give you identical return.

 string s1 = Concatenate(ListOfValues, ", ");
string s2 = ListOfValues.Concatenate(", ");

The results will be:

Orange, Apple, Watermelon, Grape, Peach, Banana.

So far, these are the simplest solution to concatenate the elements inside a collection into a delimited string.

Comments

  • Anonymous
    June 26, 2009
    Can't you just use String.Join()? http://msdn.microsoft.com/en-us/library/system.string.join.aspx

  • Anonymous
    June 30, 2009
    @dc: Yes you can. With String.Join, you have to have an array of string. If the collection is not an array, or the array is not an array of string, the application will have create an array of string, which will have negative impact on performance. This approach works on different kind of collection. Last, this approach can be customized. Let says you need a different delimiter between the last two elements, to have something like: Orange, Apple, Watermelon, Grape, Peach and Banana. Thanks for your feedback.