![](/img/trans.png)
[英]C# Linq check if a list contains all of another lists items when comparing on one property
[英]Check if one list contains all items from another list in order
如何确定列表 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 中的所有元素,但这并不要求它们的顺序相同。
这需要ListA
每个部分并将其与ListB
与SequenceEqual
进行比较:
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
。
这是一个快速的方法:
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<T>(this IEnumerable<T> outer,
IEnumerable<T> 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<T>
的相同扩展方法的更有效版本:
public static bool ContainsSequence<T>(this List<T> outer, List<T> 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;
}
使用String.Join()
将 ListA 元素连接在一起。 然后再次使用它将 ListB 元素连接在一起。 然后使用ConcatListA.IndexOf(ConcatListB)
。
我认为我的版本效率更高。
public static class CollectionExtension
{
public static bool SequenceContain<T>(this IEnumerable<T> target, IEnumerable<T> 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<T>.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();
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.