861

Is there a function in C# to quickly convert some collection to string and separate values with delimiter?

For example:

List<string> names --> string names_together = "John, Anna, Monica"

bluish
  • 26,356
  • 27
  • 122
  • 180
nan
  • 19,595
  • 7
  • 48
  • 80

3 Answers3

1650

You can use String.Join. If you have a List<string> then you can call ToArray first:

List<string> names = new List<string>() { "John", "Anna", "Monica" };
var result = String.Join(", ", names.ToArray());

In .NET 4 you don't need the ToArray anymore, since there is an overload of String.Join that takes an IEnumerable<string>.

In newer versions of .NET different String.Join overloads use different approaches to produce the result. And this might affect the performance of your code.

For example, those that accept IEnumerable use StringBuilder under the hood. And the one that accepts an array uses a heavily optimized implementation with arrays and pointers.

Results:

John, Anna, Monica

Bobrovsky
  • 13,789
  • 19
  • 80
  • 130
Quartermeister
  • 57,579
  • 7
  • 124
  • 111
  • 9
    `string.Join` (lowercase `string`) is preferable over the uppercase because it saves you from having to add `using System;` at the top of the file in some cases. – Marcel Gruber Nov 14 '22 at 20:43
133

You can also do this with linq if you'd like

var names = new List<string>() { "John", "Anna", "Monica" };
var joinedNames = names.Aggregate((a, b) => a + ", " + b);

Although I prefer the non-linq syntax in Quartermeister's answer and I think Aggregate might perform slower (probably more string concatenation operations).

Bob
  • 97,670
  • 29
  • 122
  • 130
  • 36
    Thanks for the fast replies, both works fine. You're right I did a small performance measurement using Stopwatch class and the linq-way is much slower: String.Join(", ", names.ToArray()); --> took 18 ticks Aggregate((a, b) => a + ", " + b) --> took 736 ticks – nan Aug 26 '10 at 13:09
  • 4
    Yeah I think `Aggregate` is better for Math type operations. With strings this operation it is similar to `for each` ing and just appending to a string which is very slow in inefficient because you are creating a new string for each item that exists in the list. – Bob Aug 26 '10 at 13:26
  • 1
    Note that Aggregate without a seed value will throw an InvalidOperationException if the container is empty. Use the seeded version Aggregate(seed, func) to avoid error handling code or conditional checks. String.Join does not throw on empty so no seed or extra code is required... plus it doesn't require Linq and the syntax is a little clearer. – Huacanacha Nov 25 '15 at 21:58
  • 1
    Aggregate in the example above may work faster if you'll use StringBuilder. Using '+' to perform multiple concatenation is not recommended. See Remarks section in here (https://msdn.microsoft.com/en-us/library/system.text.stringbuilder(v=vs.110).aspx) – Ilya Denisov May 10 '18 at 09:47
  • 1
    I've found that `StringBuilder.AppendJoin()` looks like exactly what the op need: `var names = new List() { "John", "Anna", "Monica" }; string joinedNames = new StringBuilder().AppendJoin(", ", names);` It's roughly same as `string.Join()`, I've not preformance-tested this. In case you desperately need a Linq form, without aggregation: `var names = new List() { "John", "Anna", "Monica" }; var joinedNames = new System.Text.StringBuilder(); names.ForEach(a => joinedNames.Append((joinedNames.Length > 0 ?", " : "") + a)); //joinedNames.ToString();` – Dinosaure Nov 05 '21 at 09:39
3

An extension method based on the accepted answer, that I use in all my projects:

public static string StringJoin(this IEnumerable<string> values, string separator)
{
    return string.Join(separator, values);
}

Usage:

var result = names.StringJoin(", ");

P.S. Don't ever use Aggregate for this, it is two orders of magnitude slower than string.Join

Alex from Jitbit
  • 53,710
  • 19
  • 160
  • 149