从 C# 中的 Enumerable 中准确获取 x 值的最佳方法是什么。 如果我像这样使用 Enumerable .Take() :
var myList = Enumerable.Range(0,10);
var result = myList.Take(20);
结果将只有 10 个元素。
我想用默认值填充缺失的条目。 像这样:
var myList = Enumerable.Range(0,10);
var result = myList.TakeOrDefault(20, default(int)); //Is there anything like this?
C# 中有这样的函数吗?如果没有,最好的实现方法是什么?
最佳答案
你可以这样做:
var result = myList.Concat(Enumerable.Repeat(default(int), 20)).Take(20);
而且很容易把它变成一个扩展方法:
public static IEnumerable<T> TakeOrDefault<T>(this IEnumerable<T> list, int count, T defaultValue)
{
return list.Concat(Enumerable.Repeat(defaultValue, count)).Take(count);
}
但是这里有一个微妙的陷阱。 对于值类型,对于引用类型,如果您的 defaultValue
不为 null,这将非常好地工作,您正在添加多个相同的对象次。这可能不是你想要的。例如,如果你有这个:
var result = myList.TakeOrDefault(20, new Foo());
您将添加 Foo
的相同实例来填充您的集合。要解决该问题,您需要这样的东西:
public static IEnumerable<T> TakeOrDefault<T>(this IEnumerable<T> list, int count, Func<T> defaultFactory)
{
return list.Concat(Enumerable.Range(0, count).Select(i => defaultFactory())).Take(count);
}
你会这样调用它:
var result = myList.TakeOrDefault(20, () => new Foo())
当然,这两种方法可以共存,因此您可以轻松拥有:
// pad a list of ints with zeroes
var intResult = myIntList.TakeOrDefault(20, default(int));
// pad a list of objects with null
var objNullResult = myObjList.TakeOrDefault(20, (object)null);
// pad a list of Foo with new (separate) instances of Foo
var objPadNewResult = myFooList.TakeOrDefault(20, () => new Foo());
关于C# Enumerable.Take 带默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31656460/