我试图获取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;
}
我无法弄清楚如何解决这个问题。
答案 0 :(得分:2)
如果在第一个位置遇到错误符号,则重新启动序列迭代器,但不检查当前项是否与序列迭代器的开头匹配,因此实际上从不将第二个2从集合与序列中的2进行比较。
答案 1 :(得分: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;
}