tags:

views:

356

answers:

7

What is the most elegant way to return a string from a List ok, yeah, I know I can do something like

public string Convert(List<int> something)
{
   var s= new StringBuilder();
   foreach(int i in something)
     s.AppendFormat("{0} ",i);

    return s.ToString();
}

but i m sure there is a way to do this with lambdas I tried also to append to a stringbuilder but that is not doing whats expected

+9  A: 
String result = String.Join(" ", list.Select(item => item.ToString()).ToArray());

To address the null problem one could add a Where(item => item != null), use the conditional operator, or the null coalescing operator. But every "fix" added to the expression will make it less readable and elegant.

Daniel Brückner
Lets hope there are no `null`s in the list ;-p
Marc Gravell
Sorry, how is this elegant? Just because it's new and Linq'y doesn't mean it's automatically elegant. By the way I have enjoyed using Linq, just not for everything.
Ash
That can be important. Aggregate + stringbuilder would probably be better.
Dykam
Meant @ Marc Gravell
Dykam
It's a kind of elegant because it's simple and compact. It's obviously not the best or most performant solution. And I completly missed the null problem.
Daniel Brückner
If it's just a collection of type List<int> and not List<int?> wouldn't there only be 0's instead of NULLs. If it's the case, then the clause to address the "null problem" really becomes moot until you change the type parameter.
JamesEggers
@James - ah, yes - you are quite correct. Sorry, in my `null`s comment I was thinking of the more general case. My bad.
Marc Gravell
+6  A: 

Use string.Join:

string.Join(" ", something.Select(i => i.ToString()).ToArray())
Chris Shaffer
+1 - short and sweet!
Preet Sangha
Oops :) Fixed - Thanks Daniel.
Chris Shaffer
A: 
string result = list.Aggregate("", (str, i) => str + " " + i).TrimStart(' ');
Jason
You need to convert `i` to a string in the lambda.
Richard
You actually don't; it's implied by C#.
Jason
A: 

Use LINQ and accumulate:

string res = list.Select(x => x.ToString()).Aggregate("", (a,b) => a + " " + b);

and saves an intermediate array (but for a large list creates O(n) garbage strings).

Richard
+14  A: 

IMO, you were better off with your original version; LINQ is great, but it isn't the answer to every problem. In particular, the string.Join approach demands an extra array (for little gain), and the Aggregate approach uses lots of intermediate strings.

Perhaps make it an extension method, though - and lose the Format stuff:

public static string Concatenate<T>(this IEnumerable<T> source, string delimiter)
{
   var s= new StringBuilder();
   bool first = true;
   foreach(T t in source) {
      if(first) {
        first = false;
      } else {
        s.Append(delimiter);
      }
      s.Append(t);
   }    
   return s.ToString();
}
Marc Gravell
+1 couldn't agree more.
Ash
It's funny; if .NET provided a built-in function called, say, ListToString, and someone posted the answer, "Just use ListToString," everyone would call it elegant. But if someone wrote a function that did the exact same thing internally, just by seeing the code people would call it clunky. LINQ may look quite concise, but that doesn't mean there's not plenty going on under the covers.
Dan Tao
@Dan - well put. Indeed, much of LINQ is *about* hiding complexity - the complexity is still there, of course ;-p.
Marc Gravell
+1 Definitely a good point.
Chris Shaffer
After reading your solution carefully I think you are right
Miau
what do you mean by the "aggregate" approach, the LINQ?
CoffeeAddict
+1  A: 

Yet another extension method:

public static class Extensions {
    public static string Join(this List<int> list) {
        return string.Join(" ", list.Select(item => item.ToString()).ToArray());
    }
}

usage:

string s = new List<int> {1, 2, 3}.Join();
grenade
+1  A: 

Taking advantage of both StringBuilder and LINQ:

    public static string SpaceOut(this IEnumerable<int> list)
    {
        if (list.Count()==)) return string.Empty;

        var res = new StringBuilder();

        list.Take(list.Count() - 1).ToList().ForEach(i => res.Append(i.ToString() + " "));
        res.Append(list.Last().ToString());

        return res.ToString();
    }
Mike Jacobs