检查一个列表是否包含其他列表中的所有项目

如何确定列表A是否以相同的顺序包含列表B中的所有元素?

列表A可以具有列表B不具有的其他元素,但必须按列表B具有它们的顺序包含列表B的所有元素。


示例1列表A…, 4,0,6结尾):

List A: List B: 5 2 9 3 2 4 3 4 0 6 

这应该返回True


示例2列表A…, 0,4,6结尾):

 List A: List B: 5 2 9 3 2 4 3 0 4 6 

这应该返回False


我从JonSkeet中找到了这个答案,看看列表A是否包含列表B中的所有元素 ,但这并不要求它们具有相同的顺序。

这是一个快速的方法:

 var equal = listA.Count - listB.Count < 0 ? false : Enumerable.Range(0, listA.Count - listB.Count).Any(i => listA.Skip(i).Take(listB.Count).SequenceEqual(listB)); 

但是,我更喜欢使用这样的扩展方法:

 public static bool ContainsSequence(this IEnumerable outer, IEnumerable inner) { var innerCount = inner.Count(); for(int i = 0; i < outer.Count() - innerCount; i++) { if(outer.Skip(i).Take(innerCount).SequenceEqual(inner)) return true; } return false; } 

你可以这样称呼:

 var equals = listA.ContainsSequence(listB); 

这是一个特定于List的相同扩展方法的更高效版本:

 public static bool ContainsSequence(this List outer, List inner) { var innerCount = inner.Count; for (int i = 0; i < outer.Count - innerCount; i++) { bool isMatch = true; for (int x = 0; x < innerCount; x++) { if (!outer[i + x].Equals(inner[x])) { isMatch = false; break; } } if (isMatch) return true; } return false; } 

这将获取ListA每个部分,并将其与ListBSequenceEqual进行比较:

 bool containsSameSequence = ListA .Where((item, index) => index <= ListA.Count - ListB.Count) .Select((item, index) => ListA.Skip(index).Take(ListB.Count)) .Any(part => part.SequenceEqual(ListB)); 

演示

它在第一个匹配序列上返回true

使用String.Join()将ListA元素连接在一起。 然后再次使用它将ListB元素连接在一起。 然后使用ConcatListA.IndexOf(ConcatListB)

我认为我的版本效率更高。

 public static class CollectionExtension { public static bool SequenceContain(this IEnumerable target, IEnumerable that) { var targetEnumerater = target.GetEnumerator(); var thatEnumerater = that.GetEnumerator(); var thatHasValue = thatEnumerater.MoveNext(); var targetHasValue = targetEnumerater.MoveNext(); var matchCount = 0; try { while (thatHasValue && targetHasValue) { if (!EqualityComparer.Default.Equals(targetEnumerater.Current, thatEnumerater.Current)) { if (matchCount > 0) { thatEnumerater.Reset(); thatEnumerater.MoveNext(); matchCount = 0; } targetHasValue = targetEnumerater.MoveNext(); continue; } targetHasValue = targetEnumerater.MoveNext(); thatHasValue = thatEnumerater.MoveNext(); matchCount++; } return matchCount == that.Count(); } finally { thatEnumerater.Dispose(); targetEnumerater.Dispose(); } } }