我需要通过stride y返回List来将double []拆分为x个元素组。非常基本...一个循环和/或一些linq和你的全套。但是,我没有花太多时间在扩展方法上,这看起来像是一些练习的好候选人。 天真的版本会返回我在当前应用程序中寻找的内容....
(A)
public static IList<T[]> Split<T>(this IEnumerable<T> source, int every, int take)
{
/*... throw E if X is insane ...*/
var result = source
.Where ((t, i) => i % every == 0)
.Select((t, i) => source.Skip(i * every).Take(take).ToArray())
.ToList();
return result;
}
...返回类型是泛型的...... ,具体取决于您对泛型的定义。
我想......
(B)
public static IEnumerable<IEnumerable<T>> Split<T>
(this IEnumerable<T> source,int every, int take){/*...*/}
...是一个更好的解决方案......也许。
问题(S):
IList <T[]>
?总是赞赏评论,意见和苛刻的语言。
使用情况:C#.Net 4.0
答案 0 :(得分:3)
B可能是更好的选择。真正的主要变化是代码的使用者可以选择在方法的末尾使用ToList()使其成为列表,而不是被迫处理List(实际上,IList,无法迭代)
这在方法链和一般用途方面具有很多优点。 ToList()很容易被枚举,但很难走向另一个方向。因此,您可以在列表上调用Select()。Split()。OrderBy()并在foreach语句中使用结果,而不必让Linq一次遍历整个事物。
重构为yield return
单个值可能会给你一个性能加值,但是因为你基本上只是返回了Select给你的迭代器(它本身会产生一个项目)我不认为通过它自己屈服,你将获得很多好处。
答案 1 :(得分:2)
我更喜欢(B),因为它看起来更灵活。将(B)方法的输出转换为IList<T[]>
的一种方法就像将.Select(x => x.ToArray()).ToList()
链接到它一样简单,例如,
var foo =
bar.Split(someEvery, someTake).Select(x => x.ToArray()).ToList();
答案 2 :(得分:1)
在.Net 4中,您只需将返回类型更改为IEnumerable<IEnumerable<T>>
即可。
在.Net 4之前,您必须首先将内部列表转换为IEnumerable
,只需在返回时调用.Cast<IEnumerable<T>>()
上的result
。