如何在LINQ中询问“是否只有一个满足条件的元素”?

快速问题,编程问题的最佳方法是什么?“这个序列中是否只有一个元素满足X条件?” 使用Linq?

// Pretend that the .OneAndOnlyOne() method exists int[] sequence = new int[] { 1, 1, 2, 3, 5, 8 }; Assert.IsTrue(sequence.OneAndOnlyOne(x => x == 2); Assert.IsFalse(sequence.OneAndOnlyOne(x => x == 1); 

这样的事情可以通过以下方式完成:

 sequence.SingleOrDefault(x => x == 2) != null; 

但那有点笨重。

我想我可以推出自己的扩展方法,但这似乎是我的代码中常见的模式,我想确保有一个很好的干净方法来做到这一点。 有没有办法使用内置的LINQ方法?

你可以这样做:

 bool onlyOne = source.Where(/*condition*/).Take(2).Count() == 1 

这将阻止计数在多次匹配的情况下不必要地枚举大序列。

最简单的方法就是使用Count 。 Single不适合你,因为如果不存在单个元素,它会抛出exception。

LBushkin建议(在评论中)使用SequenceEqual来比较序列与另一个序列。 您可以通过使用Skip(1)跳过第一个元素并将结果序列与空序列(例如您可以从Empty获得的内容)进行比较来使用它

你可以使用这个扩展方法,我认为它应该包含在linq的标准扩展方法中:

 public static int CountUpTo(this IEnumerable sequence, int maxCount) { if (sequence == null) throw new ArgumentNullException("sequence"); if (maxCount < 0) throw new ArgumentOutOfRangeException("maxCount"); var count = 0; var enumerator = sequence.GetEnumerator(); while (count < maxCount && enumerator.MoveNext()) count += 1; return count; } 

像这样使用:

 return sequence.CountUpTo(2) == 1;