Lambdas: Aggregating Strings

Posted Fri, Jul 3 2009 10:24 by Deborah Kurata

Looping through a list to append strings is often more challenging than it should be. For example…

In C#:

string emailAddresses=string.Empty;
foreach (Customer c in custList)
{
    emailAddresses += c.EmailAddress + ";";
}

In VB:

Dim emailAddresses As String = String.Empty
For Each c As Customer In custList
    emailAddresses &= c.EmailAddress & ";"
Next

Both of these examples pose a problem because the emailAddresses string ends up with an extra “;” at the end. So you can add extra code to remove it after the loop, add code in the loop that checks whether you are on the last one and skip appending the “;”, or append the “;” to the beginning instead and skip the first one. In any case, it wastes time to deal with this.

NOTE: The definition of the Customer class and the list of customers (custList) used in this example can be found here.

Using lambda expressions and the Aggregate extension method, this task is a breeze:

[To begin with an overview of lambda expressions, start here.]

In C#:

string email = custList.Select(c => c.EmailAddress)
        .Aggregate((items, item) => items + "; " + item);

In VB:

Dim email As String = custList.Select(Function(c) c.EmailAddress) _
        .Aggregate(Function(items, item) items & "; " & item)

The Select method first selects the email address for each customer. The Aggregate method then appends the email addresses together. And this code correctly handles the '”;” so you don’t have to think about it.

Enjoy!

Filed under: , , , ,

Comments

# re: Lambdas: Aggregating Strings

Friday, July 03, 2009 12:54 PM by Shawn Wildermuth

The other problem here is that the aggregation of the strings is cool, but the string + string approach involves creation of a lot of strings for the GC to clear.  You should be usng a StringBuilder.  This is very inefficient on a large number of strings:

string final = "";

for (var x = 0; x < 10; ++x)

{

 final += x.ToString();

}

This simple code (like your aggregation) will create about 30 strings that aren't used.  Being mindful of the immutability of strings is important.

# re: Lambdas: Aggregating Strings

Saturday, July 04, 2009 10:03 PM by Jonathan

I prefer using string.join to accomplish these kinds of things -- the only downside is that it needs a string[].  Luckily, LINQ includes ToArray() to turn the IEnumerable<string> that comes out of Select into a string[].

string email = string.join("; ",custList.Select(c => c.EmailAddress).ToArray());

# Lamdas

Monday, July 06, 2009 10:24 AM by Greg

It's easier to visualy inspect and verify that the for loop exmple works than the lambda based one.

# re: Lambdas: Aggregating Strings

Monday, July 06, 2009 12:39 PM by Deborah Kurata

Hey Shawn -

Thanks for stopping by my blog.

Yes, just because you can do something does not necessarily mean that you should. Have you seen the scuba diving cat? :-)

www.youtube.com/watch

As developers, we always have to evaluate techniques for "fitness of purpose". We have to decide whether a specific technique is appropriate for what our application needs to achieve.

This technique may be fine for an application that will have 1 to 5 email addresses. But it would not work well for a spamming app sending to hundreds of email addresses.

Thanks for your thoughts!

# re: Lambdas: Aggregating Strings

Monday, July 06, 2009 12:46 PM by Deborah Kurata

Hi Jonathan -

Thanks for your suggestion.

It appears that Join is smarter and does not create the excess strings that the Aggregate method creates.

Cool! Thanks again!

# Lambda Expressions: An Introduction

Sunday, October 11, 2009 6:57 PM by Deborah's Developer MindScape

My presentation at our local Code Camp was fun. I covered a lot of material and had a GREAT audience

Leave a Comment

(required) 
(required) 
(optional)
(required)