我有一个客户Ids[customerIdsList]
的C#泛型列表集合。让我们说它的数量是25。
我需要以10个为一组传递这些ID [一个可以配置并从app.config中读取的值]
到另一个方法ProcessCustomerIds()
,它将逐个处理这个客户ID。
即。第一次迭代将通过10,接下来将通过接下来的10个客户ID,最后一次将通过5个Ids ......依此类推......等等...
如何使用Linq实现这一目标? 我可以使用Math.DivRem来做这个吗?
int result=0;
int quotient = Math.DivRem(customerIdsList.Count, 10, out result)
Output:
quotient=2
result=5
因此,我将迭代customerIdsList 2次,并在每一步中调用ProcessCustomerIds()
。
如果结果值大于0,那么我将执行customerIdsList.Skip(25-result)以从集合中获取最后5个customerIds。 有没有其他更清洁,更有效的方法来做到这一点?请指教。
答案 0 :(得分:3)
在我们的项目中,我们有一个扩展方法“Slice”,它完全符合您的要求。它看起来像这样:
public static IEnumerable<IEnumerable<T>> Slice<T>(this IEnumerable<T> list, int size)
{
var slice = new List<T>();
foreach (T item in list)
{
slice.Add(item);
if (slice.Count >= size)
{
yield return slice;
slice = new List<T>();
}
}
if (slice.Count > 0) yield return slice;
}
你这样使用它:
customerIdsList.Slice(10).ToList().ForEach(ProcessCustomerIds);
此实现的一个重要特性是它支持延迟执行。 (与使用GroupBy的方法相反)。当然,这在大多数情况下并不重要,但有时也会如此。
答案 1 :(得分:3)
您可以随时使用此功能对集合进行分组:
var n = 10;
var groups = customerIdsList
.Select((id, index) => new { id, index = index / n })
.GroupBy(x => x.index);
然后,只需遍历这些组,一次将一个组成员发送给服务器一个组。
答案 2 :(得分:1)
是的,您可以使用Skip
和Take
方法。
例如:
List <MyObject> list = ...;
int pageSize = 10;
int pageNumber = list.Count / pageSize;
for (int i =0; i<pageNumber; i++){
int currentItem = i * pageSize;
var query = (from obj in list orderby obj.Id).Skip(currentItem).Take(pageSize);
// call method
}
如果您想使用Skip
和Take
,请务必订购此列表。
答案 3 :(得分:0)
一个简单的扩展名:
public static class Extensions
{
public static IEnumerable<IEnumerable<T>> Chunks<T>(this List<T> source, int size)
{
for (int i = 0; i < source.Count; i += size)
{
yield return i - source.Count > size
? source.Skip(i)
: source.Skip(i).Take(size);
}
}
}
然后使用它:
var chunks = customerIdsList.Chunks(10);
foreach(var c in chunks)
{
ProcessCustomerIds(c);
}