【问题标题】:chunking an enumerable via linq [duplicate]通过 linq 对可枚举进行分块 [重复]
【发布时间】:2016-06-08 19:44:01
【问题描述】:

我有一个 IEnumerable。我想把它分块,即说有 500 个元素,我想要 10 50 个元素块。我试过这个

        while (true)
        {
            var page = ret.Take(pagesize).ToList();
            .. do stuff with page
        }

但每次都是从头开始。我对上述模型(每页上的外部循环)感到满意。或者看起来像这样的东西

 ret.ChunkIt(pagesize).Select(chunk => >do stuff with the page)

我想避免使整个列表具体化的东西(它可能很大)。即做某事

 List<List<object>> chunks = ret.Chunkit(100);

【问题讨论】:

  • Skip() 然后 Take()
  • 这就是所谓的 schlemeil 画家算法
  • 如果集合实现了 IList 则不是 O(1)

标签: c# linq


【解决方案1】:

我已经为我从事的一个开源项目实现了类似的功能,并进行了一些更改以使其作为扩展程序工作

public static class Extension 
{

    private IEnumerable<T> Segment<T>( IEnumerator<T> iter, int size, out bool cont )
    {
        var ret= new List<T>( );
        cont = true;
        bool hit = false;
        for ( var i=0 ; i < size ; i++ )
        {
            if ( iter.MoveNext( ) )
            {
                hit = true;
                ret.Add( iter.Current );
            }
            else
            {
                cont = false;
                break;
            }
        }

        return hit ? ret : null;
    }

    /// <summary>
    /// Breaks the collection into smaller chunks
    /// </summary>
    public IEnumerable<IEnumerable<T>> Chunk<T>(this IEnumerable<T> collection, int size )
    {

        bool shouldContinue = collection!=null && collection.Any();

        using ( var iter = collection.GetEnumerator( ) )
        {
            while ( shouldContinue )
            {
                //iteration of the enumerable is done in segment
                var result = Segment( iter, size, out shouldContinue );

                if ( shouldContinue || result != null )
                    yield return result;

                else yield break;
            }
        }

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-09
    • 2013-06-10
    • 1970-01-01
    • 2012-05-19
    • 2014-11-27
    相关资源
    最近更新 更多