/// <summary> /// Reports the zero-based index of the first occurrence of the specified collection in this instance /// and uses the specified <see cref="IEqualityComparer{T}"/>. /// The search starts at a specified position. /// </summary> /// <param name="s">The current collection.</param> /// <param name="t">The collection to seek.</param> /// <param name="startIndex">The search starting position.</param> /// <param name="comparer">The specified <see cref="IEqualityComparer{T}"/> instance.</param> /// <typeparam name="T">The type of element in the collection.</typeparam> /// <returns> /// The zero-based index position of value if <paramref name="t"/> is found, or -1 if it is not. /// If <paramref name="t"/> is empty, the return value is 0. /// </returns> /// <exception cref="ArgumentNullException"><paramref name="s"/> or <paramref name="t"/> is null.</exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="startIndex"/> is less than zero or greater than <see cref="IReadOnlyCollection{T}.Count">Count</see> of <paramref name="s"/>. /// </exception> public static int IndexOf <T>(this IReadOnlyList <T> s, IReadOnlyList <T> t, int startIndex, IEqualityComparer <T> comparer) where T : IEquatable <T> { Validate(s, t, startIndex); // Follow the behavior of string.IndexOf(string) method. if (t.Count == 0) { return(0); } if (s.Count == 0 || s.Count < t.Count) { return(-1); } if (comparer == null) { comparer = EqualityComparer <T> .Default; } if (t.Count == 1) { return(s.IndexOf(t[0], startIndex, comparer)); } var table = TableBuilder.BuildTable(t, comparer); var i = 0; while (startIndex + i < s.Count) { if (comparer.Equals(t[i], s[startIndex + i])) { if (i == t.Count - 1) { return(startIndex); } i++; } else { if (table[i] > -1) { startIndex += i; i = table[i]; } else { startIndex++; i = 0; } } } return(-1); }
internal static IEnumerable <int> EnumerateIndexes <T>(IReadOnlyList <T> s, IReadOnlyList <T> t, int startIndex, IEqualityComparer <T> comparer) where T : IEquatable <T> { var table = TableBuilder.BuildTable(t, comparer); var i = 0; while (startIndex + i < s.Count) { if (comparer.Equals(t[i], s[startIndex + i])) { if (i == t.Count - 1) { yield return(startIndex); startIndex++; i = 0; } else { i++; } } else { if (table[i] > -1) { startIndex += i; i = table[i]; } else { startIndex++; i = 0; } } } }