Skip to content

Commit bad8004

Browse files
authored
Avoid multiple enumerations in Repeat via caching
Merge of PR #514 that closes #489
1 parent a65d481 commit bad8004

File tree

2 files changed

+25
-13
lines changed

2 files changed

+25
-13
lines changed

MoreLinq.Test/RepeatTest.cs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
namespace MoreLinq.Test
22
{
3+
using System.Collections.Generic;
34
using NUnit.Framework;
45

56
/// <summary>
@@ -26,13 +27,16 @@ public void TestRepeatBehavior()
2627
const int count = 10;
2728
const int repeatCount = 3;
2829
var sequence = Enumerable.Range(1, 10);
29-
var result = sequence.Repeat(repeatCount);
30+
31+
int[] result;
32+
using (var ts = sequence.AsTestingSequence())
33+
result = ts.Repeat(repeatCount).ToArray();
3034

3135
var expectedResult = Enumerable.Empty<int>();
3236
for (var i = 0; i < repeatCount; i++)
3337
expectedResult = expectedResult.Concat(sequence);
3438

35-
Assert.AreEqual(count * repeatCount, result.Count());
39+
Assert.That(result.Length, Is.EqualTo(count * repeatCount));
3640
Assert.That(result, Is.EqualTo(expectedResult));
3741
}
3842

@@ -52,11 +56,12 @@ public void TestNegativeRepeatCount()
5256
[Test]
5357
public void TestRepeatForeverBehaviorSingleElementList()
5458
{
55-
var value = 3;
56-
57-
var result = new[] { value }.Repeat();
58-
59-
Assert.IsTrue(result.Take(100).All(x => x == value));
59+
const int value = 3;
60+
using (var sequence = new[] { value }.AsTestingSequence())
61+
{
62+
var result = sequence.Repeat();
63+
Assert.IsTrue(result.Take(100).All(x => x == value));
64+
}
6065
}
6166

6267
/// <summary>
@@ -70,13 +75,16 @@ public void TestRepeatForeverBehaviorManyElementsList()
7075
const int takeCount = repeatCount * rangeCount;
7176

7277
var sequence = Enumerable.Range(1, rangeCount);
73-
var result = sequence.Repeat();
78+
79+
int[] result;
80+
using (var ts = sequence.AsTestingSequence())
81+
result = ts.Repeat().Take(takeCount).ToArray();
7482

7583
var expectedResult = Enumerable.Empty<int>();
7684
for (var i = 0; i < repeatCount; i++)
7785
expectedResult = expectedResult.Concat(sequence);
7886

79-
Assert.That(expectedResult, Is.EquivalentTo(result.Take(takeCount)));
87+
Assert.That(expectedResult, Is.EquivalentTo(result));
8088
}
8189

8290
/// <summary>

MoreLinq/Repeat.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ namespace MoreLinq
1919
{
2020
using System;
2121
using System.Collections.Generic;
22+
using Experimental;
2223

2324
public static partial class MoreEnumerable
2425
{
@@ -53,11 +54,14 @@ public static IEnumerable<T> Repeat<T>(this IEnumerable<T> sequence)
5354

5455
static IEnumerable<T> RepeatImpl<T>(IEnumerable<T> sequence, int? count)
5556
{
56-
while (count == null || count-- > 0)
57+
var memo = sequence.Memoize();
58+
using (memo as IDisposable)
5759
{
58-
// TODO buffer to avoid multiple enumerations
59-
foreach (var item in sequence)
60-
yield return item;
60+
while (count == null || count-- > 0)
61+
{
62+
foreach (var item in memo)
63+
yield return item;
64+
}
6165
}
6266
}
6367
}

0 commit comments

Comments
 (0)