处理集合中的集合

时间:2011-10-19 10:39:53

标签: c# linq

我有一个客户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。 有没有其他更清洁,更有效的方法来做到这一点?请指教。

4 个答案:

答案 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)

是的,您可以使用SkipTake方法。

例如:

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
}

如果您想使用SkipTake,请务必订购此列表。

答案 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);
}