views:

171

answers:

6

I want to turn an array or list of ints into a comma delimited string, like this:

string myFunction(List<int> a) {
    return string.Join(",", a);
}

But string.Join only takes List<string> as the second parameter. What is the best way to do this?

+19  A: 

The best way is to upgrade to .NET 4.0 where there is an overload that does what you want:

If you can't upgrade, you can achieve the same effect using Select and ToArray.

    return string.Join(",", a.Select(x => x.ToString()).ToArray());
Mark Byers
My answer was obviously better but I'll throw you a bone.
ChaosPandion
Also assumes he is at least on C# 3, .NET 3.5
Anthony Pegram
that's one neat solution!
Stefanvds
Why use LINQ instead of the built-in `ToArray` method of `List<T>`?
Steven Sudit
because he would have a List<int>. The linq select converts the List<int> to IEnumerable<string> and then to the array.
gbogumil
Upgrading to 4.0 is not practical in my situation, but the LINQ solution is exactly what I was looking for. Thanks!
Code Commander
@gbogumil: Sorry, didn't notice it was an `int`.
Steven Sudit
A: 

This answer is for you if you don't want to venture into the depths of .NET 4.0 just yet.

String.Join() concatenates all the elements of a string array, using the specified separator between each element.

The syntax is

public static string Join(
    string separator,
    params string[] value
)

Rather than passing your List of ints to the Join method, I suggest building up an array of strings first.

Here is what I propose:

static string myFunction(List<int> a) {
    int[] intArray = a.ToArray();
    string[] stringArray = new string[intArray.Length];

    for (int i = 0; i < intArray.Length; i++)
    {
        stringArray[i] = intArray[i].ToString();
    }

    return string.Join(",", stringArray);
}
Greg
This is a decent approach if someone is still on 2.0. However, `intArray` is unnecessary. `List<int>` is indexable and has a `Count` property, making the conversion to an array superfluous. You also might want to make the joining character a parameter rather than hardcoding it into the method.
Anthony Pegram
+1  A: 

Had a similar Extension Method that I modified to this

public static class MyExtensions
{
    public static string Join(this List<int> a, string splitChar)
    {
        return string.Join(splitChar, a.Select(n => n.ToString()).ToArray());
    }
}

and you use it like this

var test = new List<int>() { 1, 2, 3, 4, 5 };
string s = test.Join(",");

.NET 3.5

Jonas Elfström
Not sure I like this. `IEnumerable<T>` already has a `Join` method, and this new method performs a completely different operation, making its use counterintuitive. Secondly, if you *were* going to create this method, go ahead and make it generically applicable.
Anthony Pegram
It's a hack mimicking the join method on arrays in Ruby. http://ruby-doc.org/core/classes/Array.html#M002182
Jonas Elfström
Also .ToString() does not always return a string representation of T so I guess that could really cause some confusion.
Jonas Elfström
+1  A: 

.NET 2.0:

static string IntListToDelimitedString(List<int> intList, char Delimiter)
{
    StringBuilder builder = new StringBuilder();

    for (int i = 0; i < intList.Count; i++)
    {
        builder.Append(intList[i].ToString());

        if (i != intList.Count - 1)
            builder.Append(Delimiter);
    }

    return builder.ToString();
}
Kyle Rozendo
A good 2.0 approach. You might want to make the joining character a parameter rather than hardcoding it into the method.
Anthony Pegram
@Anthony - Good point. Done.
Kyle Rozendo
A typical optimization is to append the delimiter without testing, then remove the last character once you get out of the loop.
Steven Sudit
@Steven - I was thinking about it, but I think this would also depend on the length of the string (without testing I am unsure), so I stuck to the simple bool check.
Kyle Rozendo
I suspect the optimization would only be measurable for long strings. Having said that, I don't think it would be slower for even short ones.
Steven Sudit
+3  A: 

A scalable and safe implementation of a generic enumerable string join for .Net 3.5. The usage of iterators is so that the join string value is not stuck on the end of the string. Works correctly with 0, 1 and more elements:

public static class StringExtensions
{
    public static string Join<T>(this string joinWith, IEnumerable<T> list)
    {
        if (list == null)
            throw new ArgumentNullException("list");
        if (joinWith == null)
            throw new ArgumentNullException("joinWith");

        var stringBuilder = new StringBuilder();
        var enumerator = list.GetEnumerator();

        if (!enumerator.MoveNext())
            return string.Empty;

        while (true)
        {
            stringBuilder.Append(enumerator.Current);
            if (!enumerator.MoveNext())
                break;

            stringBuilder.Append(joinWith);
        }

        return stringBuilder.ToString();
    }
}

Usage:

var arrayOfInts = new[] { 1, 2, 3, 4 };
Console.WriteLine(",".Join(arrayOfInts));

var listOfInts = new List<int> { 1, 2, 3, 4 };
Console.WriteLine(",".Join(listOfInts));

Enjoy!

Chris Smith
+1: This is my preferred way pre .NET 4.0. Much more scalable than producing an entirely new array of strings from a list of ints so that `String.Join(String, String[])` can be called. Only thing I'd say is that it's unusual to see this method written as an extension on `String` as opposed to `IEnumerable<String>` - I tend to always call it at the end of a long chain of extension method calls.
Alex Humphrey
I stole the idea from Python if that is any help!
Chris Smith
A: 

USING NET 4.0

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string s = myFunction(PopulateTestList());
        this.TextBox1.Text = s;
    }
    protected List<int> PopulateTestList()
    {
        List<int> thisList = new List<int>();
        thisList.Add(22);
        thisList.Add(33);
        thisList.Add(44);

        return thisList;
    }
    protected string myFunction(List<int> a)
    {
        return string.Join(",", a);
    }
}