1

Possible Duplicate:
Most efficent way of joining strings

I have a List. What would be the best possible way to create a single sting having all the strings in List but separated by ','.

Thanks in advance

Community
  • 1
  • 1
Ananth
  • 10,330
  • 24
  • 82
  • 109

4 Answers4

19

Probably:

var str = string.Join(",", yourList);

If you aren't using .NET Framework 4, the overload for IEnumerable is missing so you need to convert it to an array first:

var str = string.Join(",", yourList.ToArray()); 

You can read more about string.Join at MSDN.

vcsjones
  • 138,677
  • 31
  • 291
  • 286
  • Very nice that they finally included this overload in .NET 4. Prior to that, the only option was to pass in a `string[]` ...which is essentially explained in this answer...therefore there is no reason for my comment. :) – Dr. Wily's Apprentice Jan 24 '12 at 20:24
3

One of several options:

var concat = String.Join(",", mylist.ToArray());
Ian Jacobs
  • 5,456
  • 1
  • 23
  • 38
2
public string getStringFromList(List<string> inputList){
    string returnString = "";
    if(inputList.length < 1)return returnString;
    foreach(string s in inputList){
      returnString += s + ",";
    }
    returnString = returnString.Substring(returnString.length - 2);//remove extra ","
    return returnString
}
Travis J
  • 81,153
  • 41
  • 202
  • 273
1

Fun with Iterators!

Define a Delimit extension method (shown below) and you can do this:

result = string.Concat(values.Delimit(","));

(All extension methods are contained in a code sample at the bottom)

Why would you want to have a Delimit extension method, when string.Join would work perfectly fine in this sceanrio?

Well, you could take it a step further by adding an overload that takes prefix and suffix parameters. You could use this to produce a CSV string, for example, as shown below:

// replace " with ""
var escapedValues = values.Select(x => x.Replace("\"", "\"\""));
result = string.Concat(escapedValues.Delimit(",", "\"", "\""));

Take it yet another step further and add an overload with "intelligent" (i.e. delegate) delimiters. For example, below shows the same CSV approach as above, but this time values are only surrounded by quotes if they contain whitespace or a comma:

char[] quotables = new char[] { ' ', '\t', '\r', '\n', ',' };
var result3 = string.Concat(escapedValues.Delimit(
    (previous, current) => ",", // always separate with a comma
    // but only surround with quotes if the value contains whitespace or an embedded comma
    current => current.IndexOfAny(quotables) < 0 ? null : "\"",
    current => current.IndexOfAny(quotables) < 0 ? null : "\""));

Ok, all of these previous examples can still be accomplished by some combination of existing Linq methods and the string.Join method. The following examples demonstrate some things that, I think, can't be done with those built-in methods.

You can have variable separators. The following example separates integers with either "<", ">", or "=" depending on the two values being separated. This example also uses an overload that takes a Func<int, string> convert parameter:

var rng = new Random();
int[] integers = new int[100];
for (int i = 0; i < integers.Length; i++)
    integers[i] = rng.Next(0, 100);

result = string.Concat(integers.Delimit(
    (current) => current.ToString(), // convert int to string
    // separate with either "<", ">", or "="
    (previous, current) => (previous < current) ? " < " : (previous > current) ? " > " : " = ",
    // no prefix or suffix
    null,
    null));

Output: 9 < 46 = 46 < 76 < 98 > 63 < 93 > 70 ...

Finally, not that this is something that one should necessarily do, but for the purposes of demonstration, suppose you have a list of web UI controls (List<System.Web.UI.Control>), and you want to insert an HTML <label> control before each TextBox control:

result = controls.Delimit(
    null, // no separator
    (current) => {
        var textbox = current as System.Web.UI.WebControls.TextBox;
        if (textbox == null)
            return null;
        // prefix all TextBox controls with a <label> element
        var label = new System.Web.UI.HtmlControls.HtmlGenericControl("label");
        label.Attributes["for"] = textbox.ClientID;
        label.InnerText = textbox.Attributes["name"];
        return label; },
    null); // no suffix

Below are the extension methods used by the code examples above:

static class DelimitExtensions
{
    public static IEnumerable<T> Delimit<T>(this IEnumerable<T> source, T separator)
    {
        using (var enumerator = source.GetEnumerator())
        {
            if (enumerator.MoveNext())
            {
                yield return enumerator.Current;

                while (enumerator.MoveNext())
                {
                    yield return separator;

                    yield return enumerator.Current;
                }
            }
        }
    }

    public static IEnumerable<T> Delimit<T>(this IEnumerable<T> source, T separator, T prefix, T suffix)
    {
        using (var enumerator = source.GetEnumerator())
        {
            if (enumerator.MoveNext())
            {
                yield return prefix;
                yield return enumerator.Current;
                yield return suffix;

                while (enumerator.MoveNext())
                {
                    yield return separator;

                    yield return prefix;
                    yield return enumerator.Current;
                    yield return suffix;
                }
            }
        }
    }

    public static IEnumerable<T> Delimit<T>(this IEnumerable<T> source, Func<T, T, T> separator, Func<T, T> prefix, Func<T, T> suffix)
    {
        using (var enumerator = source.GetEnumerator())
        {
            if (enumerator.MoveNext())
            {
                if (prefix != null)
                    yield return prefix(enumerator.Current);

                yield return enumerator.Current;

                if (suffix != null)
                    yield return suffix(enumerator.Current);

                T previous = enumerator.Current;

                while (enumerator.MoveNext())
                {
                    if (separator != null)
                        yield return separator(previous, enumerator.Current);

                    if (prefix != null)
                        yield return prefix(enumerator.Current);

                    yield return enumerator.Current;

                    if (suffix != null)
                        yield return suffix(enumerator.Current);

                    previous = enumerator.Current;
                }
            }
        }
    }

    public static IEnumerable<TOut> Delimit<TIn, TOut>(this IEnumerable<TIn> source, Func<TIn, TOut> convert, Func<TIn, TIn, TOut> separator, Func<TIn, TOut> prefix, Func<TIn, TOut> suffix)
    {
        using (var enumerator = source.GetEnumerator())
        {
            if (enumerator.MoveNext())
            {
                if (prefix != null)
                    yield return prefix(enumerator.Current);

                yield return convert(enumerator.Current);

                if (suffix != null)
                    yield return suffix(enumerator.Current);

                TIn previous = enumerator.Current;

                while (enumerator.MoveNext())
                {
                    if (separator != null)
                        yield return separator(previous, enumerator.Current);

                    if (prefix != null)
                        yield return prefix(enumerator.Current);

                    yield return convert(enumerator.Current);

                    if (suffix != null)
                        yield return suffix(enumerator.Current);

                    previous = enumerator.Current;
                }
            }
        }
    }
}
Dr. Wily's Apprentice
  • 10,212
  • 1
  • 25
  • 27