Ответ 1
Вы можете сделать:
bool onlyOne = source.Where(/*condition*/).Take(2).Count() == 1
Это не позволит счету перечислить большую последовательность без необходимости в случае нескольких совпадений.
Быстрый вопрос, какой предпочтительный способ запрограммировать вопрос: "Существует ли ровно один элемент в этой последовательности, который удовлетворяет условию Х?" используя 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. Единый не будет работать для вас, потому что он генерирует исключение, если есть не только один элемент.
Л. Бушкин предлагает (в комментариях) использовать SequenceEqual для сравнения последовательности с другой. Вы можете использовать это, пропустив первый элемент с помощью Skip (1) и сравнив полученную последовательность с пустой последовательностью, например, что вы можете получить из Empty
Вы можете использовать этот метод расширения, который, я думаю, должен был быть включен в стандартные методы расширения для linq:
public static int CountUpTo<T>(this IEnumerable<T> 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;