如果长度正好是一个,或者否则默认,我如何获得 IEnumerable 的第一个值?
How can I get the first value of an IEnumerable iff the length is exactly one, or default otherwise?
我想要 IEnumerable.FirstOrDefault
,但如果 length != 1
,我想要返回默认值。类似于 v.Count() == 1 ? v[0] : default
。但我更愿意在不将整个可枚举对象转换为数组的情况下这样做。获得此行为的最佳方法是什么?
您是否尝试过编写自定义扩展方法,例如:
public static TSource MyFirstOrDefault<TSource>(this IEnumerable<TSource> source)
{
return source.Count() == 1 ? source.First() : default(TSource);
}
但您需要记住,方法 Count()
和 First()
需要实例化内部元素集合才能获得计数(或第一个元素)。
希望对你有所帮助。
最好避免多次迭代可枚举项,因为并非所有可枚举项都重复相同的值。
为了确保您的可枚举只有 returns 1 个元素,最有效的方法是从可枚举中取出前两个元素并将结果转换为数组。如果数组有两个元素,您就知道可枚举项有多个元素,而无需迭代整个可枚举项。一个可枚举值有可能无限长。
下面是操作方法:
public static T OneOnlyThenFirstOrDefault<T>(this IEnumerable<T> source)
{
var beginning = source.Take(2).ToArray();
return beginning.Length == 1 ? beginning[0] : default(T);
}
Microsoft 的 Enumerable.FirstOrDefault 实现直接与底层枚举器一起工作。你的也可以:
public static T FirstIfOnlyOne<T>(this IEnumerable<T> source, T defaultValue = default(T))
{
// (Null check and IList<T> optimization omitted...)
using (IEnumerator<T> enumerator = source.GetEnumerator())
{
if (enumerator.MoveNext()) // Is there at least one item?
{
T item = enumerator.Current; // Save it.
if (!enumerator.MoveNext()) // Is that it?
return item;
}
}
return defaultValue;
}
这可能是最有效的实施方式。
我想要 IEnumerable.FirstOrDefault
,但如果 length != 1
,我想要返回默认值。类似于 v.Count() == 1 ? v[0] : default
。但我更愿意在不将整个可枚举对象转换为数组的情况下这样做。获得此行为的最佳方法是什么?
您是否尝试过编写自定义扩展方法,例如:
public static TSource MyFirstOrDefault<TSource>(this IEnumerable<TSource> source)
{
return source.Count() == 1 ? source.First() : default(TSource);
}
但您需要记住,方法 Count()
和 First()
需要实例化内部元素集合才能获得计数(或第一个元素)。
希望对你有所帮助。
最好避免多次迭代可枚举项,因为并非所有可枚举项都重复相同的值。
为了确保您的可枚举只有 returns 1 个元素,最有效的方法是从可枚举中取出前两个元素并将结果转换为数组。如果数组有两个元素,您就知道可枚举项有多个元素,而无需迭代整个可枚举项。一个可枚举值有可能无限长。
下面是操作方法:
public static T OneOnlyThenFirstOrDefault<T>(this IEnumerable<T> source)
{
var beginning = source.Take(2).ToArray();
return beginning.Length == 1 ? beginning[0] : default(T);
}
Microsoft 的 Enumerable.FirstOrDefault 实现直接与底层枚举器一起工作。你的也可以:
public static T FirstIfOnlyOne<T>(this IEnumerable<T> source, T defaultValue = default(T))
{
// (Null check and IList<T> optimization omitted...)
using (IEnumerator<T> enumerator = source.GetEnumerator())
{
if (enumerator.MoveNext()) // Is there at least one item?
{
T item = enumerator.Current; // Save it.
if (!enumerator.MoveNext()) // Is that it?
return item;
}
}
return defaultValue;
}
这可能是最有效的实施方式。