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.