给定一系列对象(为简单起见,我将在本例中使用字符串)我想知道序列是否是另一个序列的子集,其中顺序很重要(我知道子集不是正确的单词,所以希望有人能告诉我正确的用语!)
基本上说我有一个序列
AABBCDEFG
我希望匹配其他字符串列表,使得它们在序列中的位置很重要(两个字符串中的第一个位置应该具有相同的对象,然后它将检查以下字符串等)。所以AAB将是AABBC的一个子集,但不是BCD。
使用for循环编写显然是一个非常简单的算法,例如:
bool List1ContainedInList2(List<String> list1, List<String> list2)
{
// list1 should be the same size or smaller than list2
if (list1.Count > list2.Count)
return false;
// in order all objects should be equal
for (int i = 0; i < list1.Count; i++)
{
if (list1[i]!= list2[i])
return false;
}
// all reqs met
return true;
}
但是我一直在发现LINQ可以做多少酷炫有趣的事情,我想知道是否有一种简单的方法可以使用LINQ来实现这一目标?你会怎么做?谢谢!
答案 0 :(得分:4)
最简单的方法是将较大的列表“修剪”为正确长度的序列,然后使用SequenceEqual
运算符:
return list1.Count <= list2.Count && list2.Take(list1.Count)
.SequenceEqual(list1);
或者,我们可以专注于索引(最接近您发布的代码):
return list1.Count <= list2.Count && Enumerable.Range(0, list1.Count)
.All(i => list1[i] == list2[i]);
在.NET 4.0上,我们可以Zip
序列向上(虽然Zip
具有在达到任一序列结束后停止流式处理的良好属性,但我们仍然需要Count
等式检查):
return list1.Count <= list2.Count && list1.Zip(list2, (s1, s2) => s1 == s2)
.All(b => b);
或:
// This is an interesting one...
return list1.Zip(list2, (s1, s2) => s1 == s2)
.Count(b => b) == list1.Count
我提到的所有选项除以外的最后一个快速拒绝,即他们将停止枚举并在找到第一个不匹配时返回false
。
答案 1 :(得分:0)
您也可以尝试:
return list1.Take(list2.Count).SequenceEqual(list2);