There are a few things that popped in my mind seeing this:
Generalization
The method can be used to split any enumerable/collection/array, but this is just a minor point.
EnsureValid
IMO this method does a little too much. It: checks if the parameters are valid (desiredLength != 0
, which I think should also be desiredLength > 0
given the context) and also takes action to prevent the application from going on (throws exceptions, in this case). I'd change it into something like the following:
private static bool IsValid(string value, int desiredLength, bool strict)
{
return value != null
&& !(value.Length == 0 && desiredLength != 0)
&& !(value.Length != 0 && desiredLength < 1)
&& !(strict && (value.Length % desiredLength != 0));
}
and let the management of special cases to the caller. In this way, the first line of the Split
method becomes something like the following:
public static string[] Split(this string value, int desiredLength, bool strict = false)
{
if(!IsValid(value, desiredLength, strict))
{
// manage the non valid case here
}
// other logic
}
Split
method
In the current case, for string
s I mean, the method seems good. In case you consider changing it for the general case, I'd suggest the following logic:
public static T[] Split<T>(this T[] value, int desiredLength, bool strict = false)
{
if(!IsValid(value, desiredLength, strict))
{
// manage invalid case
}
var numberOfItems = (int)Math.Ceiling((double)value.Length / (double)desiredLength);
var result = new T[numberOfItems];
var chunkItems = new List<T>();
for(int i = 0; i < numberOfItems; i++)
{
int chunkFirstIndex = i * desiredLength;
for(int j = 0, currentIndex = chunkFirstIndex; j < desiredLength && currentIndex < value.Length; j++, currentIndex++)
{
chunkItems.Add(value[currentIndex]);
}
result[i] = chunkItems.ToArray();
chunkItems.Clear();
}
return result;
}
Other than these things, everything else looks fine.
P.S: The code I wrote is not tested, it's there just to better explain the idea.