Getting the index of a sequence of items

冷暖自知 提交于 2019-12-12 01:37:58

问题


I was trying to get the index of a sequence of items inside an IEnumerable<T>

var collection = new[] { 1, 2, 3, 4, 5 };
var sequence   = new[] { 2, 3 };

// IndexOf is an extension method.
collection.IndexOf(sequence); // Should return 1

I wrote an IndexOf extension method for this and it works fine unless there are more than one of the first item of the sequence in collection, consecutively:

// There are two items that are 2, consecutively in the collection,
// which is the first item of the sequence.
var collection = new[] { 1, 2, 2, 3, 4, 5 };
var sequence   = new[] { 2, 3 };

collection.IndexOf(sequence); // Should return 2 but returns -1

Here is the IndexOf method:

public static int IndexOf<T>(this IEnumerable<T> collection,
    IEnumerable<T> sequence)
{
    var comparer = EqualityComparer<T>.Default;
    var counter = 0;
    var index = 0;
    var seqEnumerator = sequence.GetEnumerator();

    foreach (var item in collection)
        if (seqEnumerator.MoveNext())
        {
            if (!comparer.Equals(item, seqEnumerator.Current))
            {
                seqEnumerator.Dispose();
                seqEnumerator = sequence.GetEnumerator();
                counter = 0;

                // UPDATED AFTER MICHAEL'S ANSWER,
                // IT WORKS WITH THIS ADDED PART:
                seqEnumerator.MoveNext();
                if (comparer.Equals(item, seqEnumerator.Current))
                    counter++;
            }
            else counter++;
            index++;
        }
        else break;

    var done = !seqEnumerator.MoveNext();
    seqEnumerator.Dispose();
    return done ? index - counter : -1;
}

I couldn't figure out how to fix this.


回答1:


When you encounter wrong symbol on not first position you restarting the sequence iterator but you don't check if the current item is matching the start of the sequence iterator, so you actually never compare second 2 from collection to 2 from sequence .




回答2:


public static int IndexOf<T>(this IEnumerable<T> collection,
                                IEnumerable<T> sequence)
{
    var ccount = collection.Count();
    var scount = sequence.Count();

    if (scount > ccount) return -1;

    if (collection.Take(scount).SequenceEqual(sequence)) return 0;

    int index = Enumerable.Range(1, ccount - scount + 1)
                          .FirstOrDefault(i => collection.Skip(i).Take(scount).SequenceEqual(sequence));
    if (index == 0) return -1;
    return index;
}


来源:https://stackoverflow.com/questions/12301614/getting-the-index-of-a-sequence-of-items

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!