-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Requirement
Note: this is not essential as there is already a workaround for some cases. See workaround below. It's also probably a good idea to implement this in terms of a more general pair-enumerable function - see design section.
Add ```` functions for 1D/2D arrays - both one and zero-based. These should work similar to the FirstIndexOf functions but instead of only returning the first index, should return all indices matching the given predicate. The implementation can be either a lazy enumerable or a pre-calculated one, but the documentation should state which.
Value Proposition
Useful to have these functions to avoid having to write loops to calculate them in application code.
Workaround: AllIndicesOf
Works for 1D one-based arrays at least, to get all the indices matching a given predicate. The idea is to use invers map and then index it on ```true``. Demonstrated here: https://dotnetfiddle.net/cxeHWv.
public static IList<int> AllIndicesOf<T>(this IOneBasedArray<T> array, Func<T, bool> matcher)
{
var inverseMap = array.Map(matcher).InverseMap();
if (inverseMap.ContainsKey(true))
{
return inverseMap[true];
}
return new List<int>();
}
However, this isn't lazy as we may want and it's not clear if it works for zero-based or 2D arrays. It also isn't general in the sense that it can't do any sort of processing we'd like - it just gives back the list of matching indices.
Design Ideas
A PairEnumerable method would work to support this, either as a workaround or as a backing method to a new AllIndicesOf method. The PairEnumerable method would return an enumerable of all index/value pairs. Then standard C# Linq could be used to get the matching indices, by simply doing a Where clause and then a Select to drop the value from the tuple. Here is an example:
https://dotnetfiddle.net/gID3sS
public static IEnumerable<(int, T)> PairEnumerable<T>(this IOneBasedArray<T> array)
{
for(int i = 1; i <= array.Length; i++)
{
yield return((i, array[i]));
}
}
var indices = array.PairEnumerable().Where(p => p.Item2.StartsWith("T")).Select(p => p.Item1);
Console.WriteLine("Positive integers less than or equal 3 starting with 'T': " + string.Join<int>(",", indices));