How do I check if IEnumerable has a single element?
var exactlyOne = sequence.Take(2).Count() == 1;
The Take
extension method will not throw if there is less elements, it will simply return only those available.
more direct:
public static bool HasSingle<T>(this IEnumerable<T> sequence) {
if (sequence is ICollection<T> list) return list.Count == 1; // simple case
using(var iter = sequence.GetEnumerator()) {
return iter.MoveNext() && !iter.MoveNext();
}
}
Note, however, that you can only guarantee that you can read a sequence once, so in those cases: by the simple fact of checking that there is a single item, you can no longer get the item. So you might prefer something that gives you the value if there is one:
public static bool HasSingle<T>(this IEnumerable<T> sequence, out T value)
{
if (sequence is IList<T> list)
{
if(list.Count == 1)
{
value = list[0];
return true;
}
}
else
{
using (var iter = sequence.GetEnumerator())
{
if (iter.MoveNext())
{
value = iter.Current;
if (!iter.MoveNext()) return true;
}
}
}
value = default(T);
return false;
}
To avoid the extra iteration in the other answers, you could implement your own extension:
public static bool HasExactlyOneElement<T>(this IEnumerable<T> source)
{
using (var enumerator = source.GetEnumerator())
return enumerator.MoveNext() && !enumerator.MoveNext();
}