tags:

views:

119

answers:

4

Hi I would like to take a list collection and generate a single csv line. So take this;

List<string> MakeStrings()
{
    List<string> results = new List<string>();
    results.add("Bob");
    results.add("Nancy");
    results.add("Joe");
    results.add("Jack");       
}


string ContactStringsTogether(List<string> parts)
{
    StringBuilder sb = new StringBuilder();

    foreach (string part in parts)
    {
        if (sb.Length > 0)
            sb.Append(", ");

        sb.Append(part);
     }
     return sb.ToString();
}

This returns "Bob,Nancy,Joe,Jack"

Looking for help on the LINQ to do this in a single statement. Thanks!

+5  A: 
var csv = string.Join(",", MakeStrings().ToArray());

I would personally recommend you using a real CSV parser instead of trying to do one liners that will break if your values contain a comma for example. You may read this article about rolling your own CSV parser.

Darin Dimitrov
A: 

You can use

String csv = parts.Aggregate((s1,s2) => s1+","+s2);
Jens
+3  A: 

Using LINQ to build a CSV in a single statement may not be a great idea - particularly if the amount of data is signficant. Just because something is possible with LINQ does not mean it is automatically the best way to do so.

Building a CSV string is, by it's nature, an operation that requires concatenating and reallocating strings. You can use String.Join(), but it won't automatically escape characters like commas or double quotes. In fact, there are a number of non-trivial rules that are part of generating well-formed CSV files.

What you should really consider doing is using a proven library that generates correct CSV formatted data.

If you do choose to write your own implementation, be aware that techniques that involve concatenating many strings (like the Enumerable.Aggregate() offered as an example) may result in a lot of intermediate, throw-away string instances which will drag down performance. You will probably still want to use a StringBuilder in any real-world implementation.

Sometimes the clearest and simplest structure for code is still a loop.

LBushkin
+3  A: 

There are not any one liners to do this with LINQ. Note that you can use the Aggregate method to do this, but you will be using string concatenation instead of a StringBuilder. I would consider adding an extension method for this if it something you will be doing often:

    public static string ToCsv<T>(this IEnumerable<T> source)
    {
        if (source == null) throw new ArgumentNullException("source");
        return string.Join(",", source.Select(s => s.ToString()).ToArray());
    }
Eric Hauser
This is exactly what I was looking for. This isnt for building to a CSV file its just for joing up to put on a view. Excellent!
CmdrTallen