c#
中是否有任何优雅的方法来检查List<T>
是否包含类似于List<T>
的子string.Contains(string)
?
比如说我想测试例如列表A
中是否包含列表B
List<int> A = new List<int>{ 1, 2, 3, 4, 3, 4, 5 };
List<int> B = new List<int>{ 3, 4, 5 };
重要的是,所有元素都必须完全按照该顺序进行匹配。
我知道我可以做类似的事情
bool Contains(List<Sampletype> source, List<Sampletype> sample)
{
// sample has to be smaller or equal length
if (sample.Count > source.Count) return false;
// doesn't even contain first element
if (!source.Contains(sample[0])) return false;
// get possible starts
// see https://stackoverflow.com/a/10443540/7111561
int[] possibleStartIndexes = source.Select((b, i) => b == sample[0] ? i : -1).Where(i => i != -1).ToArray();
foreach (int possibleStartIndex in possibleStartIndexes)
{
// start is too late -> can't match
if (possibleStartIndex + sample.Count - 1 > source.Count - 1) return false;
for (int index = possibleStartIndex; index < possibleStartIndex + sample.Count; index++)
{
// if one element does not match the whole sample doesn't match
if (source[index] != sample[index]) return false;
}
// if this is reached all elements of the sample matched
Debug.Log("Match found starting at index " + possibleStartIndex);
return true;
}
return false;
}
但我希望有更好的方法。
答案 0 :(得分:6)
这里是一个班轮:
var result = A.Select(a => $"{a}").Aggregate((c, n) => $"{c};{n}").Contains(B.Select(b => $"{b}").Aggregate((c, n) => $"{c};{n}"));
它基本上从每个列表创建一个字符串,并检查A字符串是否包含B字符串。这样,您不仅会得到类似 string.Contains
的方法,而且实际上就可以使用它。
编辑 为字符串聚合添加了分隔符,因为{1、2、3}将导致与{1,23}相同的字符串
编辑2 重新添加我的第一种方法,该方法确定列表B是否存在于列表A中(可能是分散的,但仍然有序):
var result = B.Intersect(A).SequenceEqual(B)
答案 1 :(得分:0)
基本上,您想滑过A
,并用B
检查该窗口的每个元素。最后一部分实际上是SequenceEqual
,我建议您使用它,但这只是解释这一点的替代方法:
bool equal = Enumerable.Range(0, A.Count() - B.Count() + 1)
.Select(i => A.Skip(i).Take(B.Count))
.Any(w => w.Select((item, i) => item.Equals(B[i])).All(item => item));