Skip to content

Arrays: All Indices Of #140

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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