C#

Divide Enumerable

More than 1 year has passed since last update.

[C#][LINQ] IEnumerable の分割 (多分実用的)
https://qiita.com/wipiano/items/eb562603f7efb7fac1aa

名前とか、配列のコピーが二回発生してたりするところが気になったんですね。

で、ボクならこう書くかなぁ的な奴。

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Collections;
using System.Linq;

namespace UnitTestProject1
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            var splitted = EnumerateNumber().Take(77).Divide(10);

            foreach (IEnumerable<int> chunk in splitted)
            {
                Console.WriteLine(string.Join(", ", chunk));
            }

            /* Output

            0, 1, 2, 3, 4, 5, 6, 7, 8, 9
            10, 11, 12, 13, 14, 15, 16, 17, 18, 19
            20, 21, 22, 23, 24, 25, 26, 27, 28, 29
            30, 31, 32, 33, 34, 35, 36, 37, 38, 39
            40, 41, 42, 43, 44, 45, 46, 47, 48, 49
            50, 51, 52, 53, 54, 55, 56, 57, 58, 59
            60, 61, 62, 63, 64, 65, 66, 67, 68, 69
            70, 71, 72, 73, 74, 75, 76

            */
        }

        private static IEnumerable<int> EnumerateNumber()
        {
            int n = 0;
            while (true)
            {
                yield return n++;
            }
        }
    }

    public static class hoge
    {
        private class Limited<T> : IEnumerable<T>
        {
            int last = 0;
            IEnumerator<T> e;

            public Limited(IEnumerator<T> e, int limit)
            {
                this.e = e;
                this.last = limit;
            }

            public IEnumerator<T> GetEnumerator()
            {
                do
                {
                    yield return e.Current;
                    last -= 1;
                }
                while (0 < last && e.MoveNext());
            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                throw new NotImplementedException();
            }
        }

        public static IEnumerable<IEnumerable<T>> Divide<T>(this IEnumerable<T> a, int _size)
        {
            var e = a.GetEnumerator();

            while (e.MoveNext()) yield return new Limited<T>(e, _size);
        }
    }
}