Ad-Hoc String Concatenation using LINQ

I regularly use functional programming and LINQ in two contexts – when writing code that is part of an example or tool that will potentially execute millions of times, and when writing ad-hoc queries.  These days, I use C# and LINQ as my ‘scripting language’, to iterate through directory structures, open and process Open XML documents, and do whatever else is part of my task at hand.  I have different coding practices when I write these ad-hoc queries.  I basically do no query optimization.  So long as my little program does what I want, I don’t care if it is inefficient.  I use different idioms for string concatenation when writing these ad-hoc queries / projections.

This blog is inactive.
New blog: EricWhite.com/blog

Blog TOCWhen you are writing small ad-hoc queries, a very common task is to concatenate a list of strings into a single string.  Sometimes you don’t need to interject any additional text between items in the source list, and sometimes you do need to interject text, such as Environment.NewLine.  I use a different idiom for each of these cases.

When writing example code or tools, I use the StringConcatenation extension method that I introduced in this topic.  I keep this method in the PtUtil.cs module (available in HtmlConverter.zip under the downloads tab at www.codeplex.com/powertools.  But when I’m writing an ad-hoc query, sometimes it’s not worth the effort to put that source file in my project.  After all, I’m going to spend only about 3 minutes (or less) to write and execute the query.

When I don’t need to interject a new line between each string, I use the Aggregate extension method as follows.

string[] stringArray = new[] {
"abc",
"def",
"ghi",
};
string str = stringArray.Aggregate((s, i) => s + i);
Console.WriteLine(str);

This outputs:

abcdefghi

When I need to interject a newline between each string, then it is necessary to supply an empty string as the seed value:

string[] stringArray = new[] {
"abc",
"def",
"ghi",
};
string str = stringArray.Aggregate("", (s, i) => s + i + Environment.NewLine);
// seed value -------------------- ^
Console.WriteLine(str);

This outputs:

abc
def
ghi

If you don’t supply the seed value when concatenating strings, then the query will concatenate the first two strings in the source collection:

string[] stringArray = new[] {
"abc",
"def",
"ghi",
};
string str = stringArray.Aggregate((s, i) => s + i + Environment.NewLine);
// no seed value here ------------ ^
Console.WriteLine(str);

This outputs:

abcdef
ghi

Using the Aggregate extension method in this fashion is not as efficient as using a StringBuilder object (the StringConcatenate extension method uses a StringBuilder).  When using Aggregate in this fashion, it creates a short-lived string object for every element in the source collection.  When writing a tool or an example, it makes sense to spend the little bit of time to include the StringConcatenate extension method, but when writing an ad-hoc query, I don’t care.