有没有办法在列表中搜索多个连续值?我查看了 Find 和 IndexOf 但 Find 使用仅使用当前值的谓词,而 IndexOf 仅采用字节参数。
我可以编写自己的解决方案,但我想确保没有解决这个常见问题的可用解决方案。
提前致谢。
一个想法可能是将您的列表分成连续值组,然后比较每个值的内容。这是另一个将执行拆分的函数(从 F# 核心库中提取)。
static IEnumerable<T[]> Windowed<T>(this IEnumerable<T> source, int size)
{
if (source == null)
throw new NullReferenceException();
if (size <= 0)
throw new ArgumentOutOfRangeException("size", "The window size must be positive.");
var arr = new T[size];
var r = size-1;
var i = 0;
foreach (T item in source)
{
arr[i] = item;
i = (i+1) % size;
if (r == 0)
{
var res = new T[size];
for (int j = 0; j < size; j++)
res[j] = arr[(i+j) % size];
yield return res;
}
else
r -= 1;
}
}
你可以像这样使用上面的函数:
var result = Enumerable.Range(1, 10).Windowed(2)
.Where(a => a[0] == 3 && a[1] == 4)
.First();
老实说,我认为这不是一个特别常见的问题 - 我很确定框架中没有任何内容。
我怀疑你需要弄清楚你是否想要效率或简单来实现你自己的。一个相当简单的扩展方法版本可能如下所示:
public static int IndexOf<T>(this IEnumerable<T> source,
T first,
T second)
{
IEqualityComparer<T> comparer = EqualityComparer<T>.Default;
// We can only return when we've read source[index+1], so we need
// to keep one value behind
int index=-1;
T prev = default(T);
foreach (T element in source)
{
if (comparer.Equals(first, prev) &&
comparer.Equals(second, element) &&
index >= 0) // Avoid edge cases where first=default(T)
{
return index;
}
index++;
prev = element;
}
return -1;
}
这是我自己对这个问题的解决方案。我喜欢这个方法,因为它可以处理任意数量的项目,是 O(n) 并且非常简单:
<Extension()> Public Function Find(Of T)(ByVal list As List(Of T), ByVal searchedValue As T(), ByVal startingIndex As Integer) As Integer
Dim mainIndex As Integer
Dim searchedIndex As Integer
Dim result As Integer
result = -1 ' Initialize result
mainIndex = startingIndex
While mainIndex < list.Count AndAlso result = -1
If list(mainIndex).Equals(searchedValue(0)) Then
searchedIndex = 0
While searchedIndex < searchedValue.Length AndAlso (list(mainIndex + searchedIndex).Equals(searchedValue(searchedIndex)))
searchedIndex = searchedIndex + 1
End While
If searchedIndex = searchedValue.Length AndAlso list(mainIndex + searchedIndex - 1).Equals(searchedValue(searchedIndex - 1)) Then
result = mainIndex
End If
End If
mainIndex = mainIndex + 1
End While
Return result
End Function