tags:

views:

4073

answers:

8

Wondering if there is an easy LINQ Expression to concatenate my entire List collection items to a single string with a Delimiter character.

UPDATE: What if the collection is of custom objects instead of String , Imagine I need to concat on object.Name

+28  A: 
String.Join(delimiter, list.ToArray());
ssg
Your arguments are wrong-way around.
Jacob Proffitt
Yup, fixed thanks :)
ssg
I am all for LINQ solutions but this is more efficient than LINQ and the Aggregate() method.
Andrew Robinson
+2  A: 

Good question. I've been using

List<string> myStrings = new List<string>{ "ours", "mine", "yours"};
string joinedString = string.Join(", ", myStrings.ToArray());

It's not LINQ, but it works.

Jacob Proffitt
+1  A: 
List<string> strings = new List<string>() { "ABC", "DEF", "GHI" };
string s = strings.Aggregate((a, b) => a + ',' + b);
Peter McGrattan
+22  A: 

By using linq, this should work;

string delimeter = ",";
List<string> items = new List<string>() { "foo", "boo", "john", "doe" };
Console.WriteLine(items.Aggregate((i, j) => i + delimeter + j));

Updated according to comments:

class description:

public class Foo
{
    public string Boo { get; set; }
}

usage:

class Program
{
    static void Main(string[] args)
    {
        string delimeter = ",";
        List<Foo> items = new List<Foo>() { new Foo { Boo = "ABC" }, new Foo { Boo = "DEF" }, 
            new Foo { Boo = "GHI" }, new Foo { Boo = "JKL" } };

        Console.WriteLine(items.Aggregate((i, j) => new Foo{Boo = (i.Boo + delimeter + j.Boo)}).Boo);
        Console.ReadKey();

    }
}

Updated-2: and here is my best :)

items.Select(i => i.Boo).Aggregate((i, j) => i + delimeter + j)
yapiskan
Thanks for the LINQ solution
Jobi Joy
What if the collection is of custom objects instead of String , Imagine I need to concat on object.Name
Jobi Joy
See my updated answer.
yapiskan
Thanks, but I didn't quite like the "new Foo" part inside the Lambda expressions of LINQ query. Is there any other easy way?.
Jobi Joy
See my last update ;)
yapiskan
thanks a lot, that is really brilliant
Jobi Joy
O(n^2) time strikes again.
Kennet Belenky
+11  A: 

This is for a string array:

string.Join(delimiter, array);

This is for a List<string>:

string.Join(delimiter, list.ToArray());

And this is for a list of custom objects:

string.Join(delimiter, list.Select(i => i.Boo).ToArray());
Alexander Prokofyev
Thanks! I've been doing the boring string.Join for string lists for ages. Today was the first time I needed to concat strings inside a list of objects containing names and other things... I'm still pretty new at LINQ, but I knew I'd find an elegant solution there, and so I did. I think your solution is prettier than the one above. ;)
neminem
+1  A: 
public class Person
{
  string FName { get; set; }
  string LName { get; set; }
}

List<Person> persons = new List<Person>();

string listOfPersons = string.Join(",", persons.Select(p => p.FName));
dev.bv
A: 

Here's another play on the theme, handling empty strings and nulls

public virtual string ToDelimitedString(string delimiter)
        {
            var lines = new []
            {
                Line1,
                Line2,
                Line3,
                Town,
                County,
                Postcode == null ? null : Postcode.Value
            };

            return lines
                .Where(l => !String.IsNullOrEmpty(l))
                .Aggregate((i, j) => i + delimiter + j);
        }
BobTodd
For me this is the same as the already given stuff and that you can place a `.Where(l => !String.IsNullOrEmpty(l)` before the `Aggregate()` is just a simple check that comes automatically if you allow such a thing beforehand.
Oliver
A: 

I think that if you define the logic in an extension method the code will be much more readable:

public static class EnumerableExtensions { 
  public static string Join<T>(this IEnumerable<T> self, string separator) {  
    return String.Join(separator, self.Select(e => e.ToString()).ToArray()); 
  } 
} 

public class Person {  
  public string FirstName { get; set; }  
  public string LastName { get; set; }  
  public override string ToString() {
    return string.Format("{0} {1}", FirstName, LastName);
  }
}  

// ...

List<Person> people = new List<Person>();
// ...
string fullNames = people.Join(", ");
string lastNames = people.Select(p => p.LastName).Join(", ");
Jordão