ToDelimitedString Extension Method

October 2nd, 2008

This has probably been done before, but I thought I would post my implementation.

Take a given generic list (or something that implements IEnumerable, and convert it to a delimited string.

First, in a static class, (I have a class called GeneralExtensions for just this sort of thing), add this code.

   1: public static string ToDelimitedString<T>(this IEnumerable<T> list, string delimiter, Func<T, string> action)
   2: {
   3:     var sb = new System.Text.StringBuilder();
   4:     foreach (var t in list)
   5:     {
   6:         sb.Append(action.Invoke(t));
   7:         sb.Append( delimiter );
   8:     }
   9:     sb.Remove(sb.Length - delimiter.Length, 1);
  10:  
  11:     return sb.ToString();
  12: }

Now if I have a customer class with a FirstName and LastName properties, like this:

   1: public class Customer
   2: {
   3:    public string Id { get; set; }
   4:    public string FirstName { get; set; }
   5:    public string LastName { get; set; }
   6: }

And I have a list of them, and want to convert them to a coma delimited list, I would do it like this:

   1: var list = new List<Customer>();
   2: list.Add(new Customer { FirstName="Tom", LastName="Bin" });
   3: list.Add(new Customer { FirstName="John", LastName"Doe" });
   4:  
   5: string result = list.ToDelimitedString(",", c => c.FirstName + " " + c.LastName);

The result will look like this: “Tom Bin, John Doe”

Chris Brandsma

  • http://tnthughes.net/blog Terry Hughes

    Chris,

    I’m curious as to why do you use a custom delegate when you can use a Func? Also, is there a reason for action.Invoke(t) rather than action(t)?

    Terry

  • http://tnthughes.net/blog Terry Hughes

    Hey, it ate my signs …

    Func should really be Func<T, string>
    And in case that didn’t work a Func that takes a T and returns a string.

  • Steve

    sb.Remove(sb.Length – 1, 1); should be
    sb.Remove(sb.Length – delimiter.Length, delimiter.Length);

    And I always use the string.Join method, first argument is your delimiter, second argument is a string array.
    return string.Join(delimiter, list.Select(action).ToArray());

  • http://elegantcode.com Chris Brandsma

    @Terry: I forgot about Func (I remembered Action, but forgot about Func). OK, fixed my code, retested, still works. Thank you for the suggestion.

    @Steve: Missed the delimiter.Length, thank you.

    I looked at string.Join, and the reason I shyed away from it was because of the ToArray. The ToArray is unlikely to cause problems, but it is slightly more direct in that a separate array does not have to be created.

    Which, for the size of the data that I’m parsing, is probably being offset by the use of the StringBuilder.

    This is what I get for posting something so quickly…but then again, it is a great way to learn/remember what is possible.

  • http://www.tobinharris.com Tobin Harris

    I like the idea of that. What about this (off top of head):

    public class Customer
    {
    //…properties
    public string FullName{ get{ return String.Format(“{0} {1}”, FirstName, LastName; } }
    }

    string result = string.Join(“,”, customers.Select(c=>c.FullName).ToArray() );

    Something like that, anyway. Or if you don’t like FulllName, would this work?

    string result = string.Join(“,”, customers.Select(c=>String.Format(“{0} {1}”, c.FirstName, c.LastName ).ToArray() );

    I also write an extension method for string to make String.Format more fluent. You can then do this:

    string fullName = “{0} {1}”.QuickFormat(c.Forename, c.Surname);

  • http://www.tobinharris.com Tobin Harris

    Doh! After posting I saw the previous comment mentioned all this. Soz.

  • http://www.elegantcode.com Chris Brandsma

    @tobin: ok, I really like the idea of the quick format. I have to do that one now.

  • http://www.elegantcode.com Chris Brandsma

    public static string QuickFormat(this string format, params object[] args )
    {
    return string.Format(format, args);
    }

blog comments powered by Disqus