wforney / morelinq

Automatically exported from code.google.com/p/morelinq
Apache License 2.0
0 stars 0 forks source link

Add sequence.IndexesOf(item) #81

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Sometimes you want to enumerate the indexes where an item appears in a sequence.

One nice benefit of implementing IndexesOf is that it sidesteps implementing 
IndexOf, which is common but has unfortunate baggage related to returning -1 
for no result.

Potential variant: IndexesOf(T, IEquater<T>)
Potential generalization: IndexesWhere

Example implementation (without eager checking):

    public static IEnumerable<int> IndexesOf<T>(this IEnumerable<T> sequence, T item) {
        if (sequence == null) throw new ArgumentNullException("sequence");
        var i = 0;
        foreach (var e in sequence) {
            if (Equals(e, item)) yield return i;
            i++;
        }
    }

Example tests:

    new string[0].IndexesOf("").AssertSequenceEquals(new int[0]);

    new[] { "a", "bra", "ca", "da" }.IndexesOf("abracadabra").AssertSequenceEquals(new int[0]);
    new[] { "a", "bra", "ca", "da" }.IndexesOf("a").AssertSequenceEquals(new[] { 0 });
    new[] { "a", "bra", "ca", "da" }.IndexesOf("bra").AssertSequenceEquals(new[] { 1 });
    new[] { "a", "bra", "ca", "da" }.IndexesOf("ca").AssertSequenceEquals(new[] { 2 });
    new[] { "a", "bra", "ca", "da" }.IndexesOf("da").AssertSequenceEquals(new[] { 3 });

    new[] { "a", "bra", "ca", "da", "bra" }.IndexesOf("bra").AssertSequenceEquals(new[] { 1, 4 });

    Enumerable.Repeat("spam", 100).IndexesOf("spam").AssertSequenceEquals(Enumerable.Range(0, 100));

Original issue reported on code.google.com by craig.gi...@gmail.com on 22 Jul 2013 at 8:04

GoogleCodeExporter commented 9 years ago
MoreLINQ already has Index[1], which can be coupled with Where to the same 
effect:

sequence.Index().Where(e => Equals(e.Value, item)).Select(e => e.Key)

It even reads like the potential generalization “IndexesWhere” you suggest.

[1] 
https://code.google.com/p/morelinq/source/browse/MoreLinq/Index.cs?name=1.0&r=9e
a817b7a5aa0983230979259523e663d356e04f

Original comment by azizatif on 22 Jul 2013 at 8:37

GoogleCodeExporter commented 9 years ago
Hm, for some reason I thought Index had a dictionary result (and thus was way 
more expensive in several ways). Nevermind then.

Original comment by craig.gi...@gmail.com on 22 Jul 2013 at 9:03