我正在创建一个函数,它将采用一些IEnumerable,进行分组,排序,获取一些前N个元素,并返回这些元素的列表。它可能会在以后做更多,这就是为什么我想把它变成一个函数,而不仅仅是直接使用LINQ。
我依靠匿名委托来指定T类型的哪些成员将用于对集合进行分组和排序。
public IEnumerable<T> GetList(IEnumerable<T> collection, Func<T, object> groupBy, Func<T, object> orderBy, int howMany)
{
var group = collection
.GroupBy(groupBy)
.Select(x => x.OrderBy(orderBy).Take(howMany))
.Aggregate((l1, l2) => l1.Concat(l2));
return group.ToList();
}
并像这样使用:
new CollectionGroupPicker<NumericDomainObject>().GetList(list, x => x.GroupableField, x => x.OrderableField, 2).ToList();
我的问题是 - 是否有更好的方法来传递哪种类型的T我将用于分组和排序?我在这里使用对象,但是有更好的方法吗?
答案 0 :(得分:2)
您应该指定组并选择键作为通用参数,而不是指定object
。它们的类型将根据用法自动推断,调用者可以指定任何返回类型的lambda。
public IEnumerable<T> GetList<TGroupKey, TOrderKey>(IEnumerable<T> collection,
Func<T, TGroupKey> groupBy,
Func<T, TOrderKey> orderBy,
int howMany)
{
var group = collection
.GroupBy(groupBy)
.Select(x => x.OrderBy(orderBy).Take(howMany))
.Aggregate((l1, l2) => l1.Concat(l2));
return group.ToList();
}
答案 1 :(得分:2)
我同意Samuel使用通用的parmater类型。另外,为什么不使用SelectMany
来展平结果,也许还可以将其作为扩展方法?
static class GetListExtensionMethods
{
public static IEnumerable<T> GetList<T, TGroupingField, TOrderingField>(this IEnumerable<T> collection, Func<T, TGroupingField> groupBy, Func<T, TOrderingField> orderBy, int howMany)
{
var group = collection
.GroupBy(groupBy)
.SelectMany(x => x.OrderBy(orderBy).Take(howMany));
return group.ToList();
}
}