1

内のアイテムのシーケンスのインデックスを取得しようとしていました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

このためのIndexOf拡張メソッドを作成しましたが、コレクション内のシーケンスの最初のアイテムが連続して複数存在しない限り、正常に動作します。

// 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

IndexOfメソッドは次のとおりです。

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

これを修正する方法がわかりませんでした。

4

2 に答える 2

3
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;
}
于 2012-09-06T14:08:55.563 に答える
2

最初の位置ではなく間違ったシンボルに遭遇した場合、シーケンスイテレータを再起動しますが、現在のアイテムがシーケンスイテレータの開始と一致しているかどうかを確認しないため、実際にはコレクションの2番目の2とシーケンスの2を比較することはありません。

于 2012-09-06T14:04:22.510 に答える