I recently learned about Linq's deferred execution and a little clearer understanding of IEnumerable. I came back to some code that I had written and decided to change with Linq extension methods. (The method is a helper function for some custom Excel functions that I use.)
Overall the code kind of feels wrong readability-wise having to tack on values = values.exension like that. When I step through the debugger it seems to be behaving like I expect.
Is there a more readable way to express this function with or without linq extension methods? I fear I'm making things less readable and possibly micro-optimizing.
private static string Concatenate(IEnumerable<string> values
, string between, string begin, string end
, bool excludeDuplicates, bool includeBlanks)
{
if (!includeBlanks)
values = values.Where(v => v != string.Empty);
if (excludeDuplicates)
values = values.Distinct();
values = values.Select(v => begin + v + end);
return string.Join(between, values);
}
Here is what I previously used in case it is of interest.
private static string Concatenate(IEnumerable<string> Values, string BetweenString
, string BeginString, string EndString, bool ExcludeDuplicates, bool IncludeBlanks)
{
IEnumerable<string> IncludedValues = (
from Value in Values
where IncludeBlanks || Value.Length > 0
select BeginString + Value + EndString
);
IEnumerable<string> StringValues;
if (ExcludeDuplicates)
StringValues = new HashSet<string>(IncludedValues);
else
StringValues = new List<string>(IncludedValues);
return string.Join(BetweenString, StringValues);
}
EDIT:
To give a little more context for this function (I'll hedge a little here and say that I haven't changed these functions to be more readable yet, so I beg forgiveness now. :) )
The purpose of this function is that it gets used by two other functions RA.VCONCATENATE and RA.HCONCATENATE that will be Excel functions (using ExcelDNA). (I do plan on changing this to be more readable as well and make Values IEnumerable instead of IList). Note: I can't have optional "missing" parameters in Excel or overloading so I made extension methods for string, int, double and bool that convert unspecified parameters to a default.
[ExcelFunction(Category = "Extra Range Functions", Name = "RA.VCONCATENATE",
Description = "Vertically Concatenates all values in the Range starting from Top to Bottom, then Left to Right.")]
public static string VerticalConcatenate(object[,] Range, object BetweenString, object BeginString, object EndString, object ExcludeDuplicates, object IncludeBlanks)
{
List<string> Values = RangeValuesToList(Range, RangeEnumerateFirstDirection.Down); //Empty cells replaced with String.Empty
string sBetweenString = BetweenString.Optional("");
string sBeginString = BeginString.Optional("");
string sEndString = EndString.Optional("");
bool bExcludeDuplicates = ExcludeDuplicates.Optional(false);
bool bIncludeBlanks = IncludeBlanks.Optional(false);
return Concatenate(Values, sBetweenString, sBeginString, sEndString, bExcludeDuplicates, bIncludeBlanks);
}
RA.HCONCATENATE is the same except is uses RangeEnumerateFirstDirection.Right. The expected output of =RA.VCONCATENATE(A1:A5, ",", "^", "$", TRUE, FALSE) (if Range [A1:B3] values are { 1, 2, 2 }, {3, EMPTY, EMPTY} ) is: "^1$,^2$,^3$". RA.HCONCATENATE output is: "^1$,^3$,^2$".
if
blocks? Or is that a description of how the code is written? Whilevalues
could be something describable as "Linq", it seems more like a generic function that could have other purposes. \$\endgroup\$