Skip to content

Arrays: All Indices Of #140

@ColmBhandal

Description

@ColmBhandal

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));

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions