The string.Join method can come in handy when you want a comma separated list of strings.  However, there's a major limitation.  To use it, you must provide a one-dimensional string array.  What if you have a collection of objects and you want to "Join" a property on the objects (e.g., a comma separated list of IDs).

Well, since I couldn't find anything within the framework that would do this for me, I wrote an extension method that meets my need.

Updated from James Curran's suggestion in the comments. 

   1: public static string Join<T>( this IEnumerable<T> target, Func<T, object> valueSelector )
   2: {
   3:     StringBuilder result = new StringBuilder();
   4:     foreach( T item in target )
   5:     {
   6:         result.Append( valueSelector( item ).ToString() );
   7:         result.Append( "," );
   8:     }
   9:     result.Length--;
  10:     //remove the trailing comma    
  11:     return result.ToString();
  12: }

This will take any Generic Enumerable and Join the string representation based on the value selector you provide.

Here is an example of how to use it:

   1: public class Child
   2: {
   3:     public int Id { get; set; }    
   4:     public string Name { get; set; }    
   5:     // ...
   6: }
   7: public class Parent
   8: {
   9:     public int Id { get; set; }
  10:     public string Name { get; set; }
  11:     public List<Child> Children;
  12:     // ...    
  13:     public string ChildIds
  14:     {
  15:         get { return Children.Join( child => child.Id ); }
  16:     }
  17:     public string ChildNames
  18:     {
  19:         get { return Children.Join( child => child.Name ); }
  20:     }
  21: }

Cheers.

posted on Thursday, June 26, 2008 2:58 PM
Filed Under [ .Net Design C# ]

Comments

Gravatar
# re: Creating a comma separated list from IEnumerable<T>
posted by Justin
on 6/27/2008 9:46 AM
I have a very similar method that I just posted for doing this using string.join and Linq.

http://www.desertpenguins.com/2008/06/27/CConvertCollectionToDelimitedStringUsingLinq.aspx

In your method, I would add a check in the join to make sure that the valueSelector(item).ToString() is NotNullOrEmpty so that you don't end up with something like 1,2,,3 instead of 1,2,3.

As a performance note, you might want to look at moving the "," to the front of the string and then doing a Substring(1) versus having to look at the string length.
Gravatar
# re: Creating a comma separated list from IEnumerable<T>
posted by James Curran
on 6/27/2008 1:19 PM
Adding Mike's suggestion to one of my own:

public static string Join<T>( this IEnumerable<T> target, Func<T, object> valueSelector )
{
StringBuilder result = new StringBuilder();
foreach( T item in target )
{
result.Append(valueSelector(item).ToString());
result.Append(",");
}
result.Length --; // removes final comma.
return result.ToString();
}
Gravatar
# re: Creating a comma separated list from IEnumerable<T>
posted by Will Smith
on 6/27/2008 8:13 PM
Hey guys thanks for your suggestions.

I cannot remember where the performance gain of using a StringBuilder really shines. So far, my lists are quite small (ten or so items), so the string concat isn't too bad. Of course, using the StringBuilder will be much better for longer lists and the performance difference will hardly be noticed on short lists.

I think I like James version best. Thanks James. The Length-- is very elegant.
Gravatar
# re: Creating a comma separated list from IEnumerable<T>
posted by Justin
on 6/27/2008 9:08 PM
The link to my code changed to http://www.desertpenguins.com/post/2008/06/C-Convert-Collection-to-Delimited-String-using-Linq.aspx.

I used to use something very similar to what James posted and just recently changed it to the following.

public string Join<T>(string delimiter, IEnumerable<T> items, Converter<T, string> converter)
{
return string.Join(delimiter, (items.Where(i => string.IsNullOrEmpty(converter(i)) == false).Select(i => converter(i))).ToArray());
}
Gravatar
# re: Creating a comma separated list from IEnumerable<T>
posted by Alden Snow
on 11/19/2009 1:26 PM
Thanks Justin, that is just what I was looking for.
Gravatar
# re: Creating a comma separated list from IEnumerable<T>
posted by Will Smith
on 11/19/2009 4:06 PM
@Justin, Aldon,

I might have reversed the order of the Select and Where. That way you only have to execute the converter once per item.

Post A Comment
Title:
Name:
Email:
Comment:
Verification: