Skip to content

Commit

Permalink
Merge pull request #517 from icarus-consulting/i516-ComparisonForDist…
Browse files Browse the repository at this point in the history
…inct

add comparison for distinct class
  • Loading branch information
MSE1188 authored Apr 8, 2022
2 parents 6144565 + bb5ee3b commit 090b1fc
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 7 deletions.
24 changes: 22 additions & 2 deletions src/Yaapii.Atoms/Enumerable/Distinct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

using System;
using System.Collections.Generic;

namespace Yaapii.Atoms.Enumerable
Expand All @@ -43,13 +44,25 @@ public Distinct(params IEnumerable<T>[] enumerables) : this(
/// The distinct elements of one or multiple Enumerables.
/// </summary>
/// <param name="enumerables">enumerables to get distinct elements from</param>
public Distinct(IEnumerable<IEnumerable<T>> enumerables) : base(() =>
public Distinct(IEnumerable<IEnumerable<T>> enumerables) : this(
enumerables,
(v1, v2) => v1.Equals(v2)
)
{ }

/// <summary>
/// The distinct elements of one or multiple Enumerables.
/// </summary>
/// <param name="enumerables">enumerables to get distinct elements from</param>
/// <param name="comparison">comparison to evaluate distinction</param>
public Distinct(IEnumerable<IEnumerable<T>> enumerables, Func<T, T, bool> comparison) : base(() =>
new LiveMany<T>(() =>
new Enumerator.Distinct<T>(
new Mapped<IEnumerable<T>, IEnumerator<T>>(
(e) => e.GetEnumerator(),
enumerables
)
),
comparison
)
),
false
Expand All @@ -73,5 +86,12 @@ public static class Distinct
/// </summary>
/// <param name="enumerables">enumerables to get distinct elements from</param>
public static IEnumerable<T> New<T>(IEnumerable<IEnumerable<T>> enumerables) => new Distinct<T>(enumerables);

/// <summary>
/// The distinct elements of one or multiple Enumerables.
/// </summary>
/// <param name="enumerables">enumerables to get distinct elements from</param>
/// <param name="comparison">comparison to evaluate distinction</param>
public static IEnumerable<T> New<T>(IEnumerable<IEnumerable<T>> enumerables, Func<T, T, bool> comparison) => new Distinct<T>(enumerables, comparison);
}
}
21 changes: 16 additions & 5 deletions src/Yaapii.Atoms/Enumerator/Distinct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

using System;
using System.Collections;
using System.Collections.Generic;

Expand All @@ -34,17 +35,27 @@ namespace Yaapii.Atoms.Enumerator
public sealed class Distinct<T> : IEnumerator<T>
{
private readonly IEnumerable<IEnumerator<T>> originals;
private readonly Func<T, T, bool> comparison;
private readonly Queue<IEnumerator<T>> buffer = new Queue<IEnumerator<T>>();
private readonly List<T> hits = new List<T>();

/// <summary>
/// Enumerator that only gives the distinct elements of multiple enumerators.
/// </summary>
/// <param name="enumerators"></param>
public Distinct(IEnumerable<IEnumerator<T>> enumerators)
public Distinct(IEnumerable<IEnumerator<T>> enumerators) : this(
enumerators,
(v1, v2) => v1.Equals(v2)
)
{ }

/// <summary>
/// Enumerator that only gives the distinct elements of multiple enumerators.
/// </summary>
public Distinct(IEnumerable<IEnumerator<T>> enumerators, Func<T, T, bool> comparison)
{
originals = enumerators;
buffer = new Queue<IEnumerator<T>>(enumerators);
this.originals = enumerators;
this.comparison = comparison;
this.buffer = new Queue<IEnumerator<T>>(enumerators);
}

/// <summary>
Expand Down Expand Up @@ -98,7 +109,7 @@ private void SkipKnown()
this.buffer.Dequeue();
}

if (buffer.Count > 0 && !this.hits.Contains(this.buffer.Peek().Current))
if (buffer.Count > 0 && !(new Enumerable.Contains<T>(this.hits, v => comparison(v, this.buffer.Peek().Current)).Value()))
{
this.hits.Add(this.buffer.Peek().Current);
break;
Expand Down
26 changes: 26 additions & 0 deletions tests/Yaapii.Atoms.Tests/Enumerable/DistinctTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

using System.Collections.Generic;
using Xunit;
using Yaapii.Atoms.Number;

namespace Yaapii.Atoms.Enumerable.Tests
{
Expand All @@ -39,6 +40,31 @@ public void MergesEntries()
).Value() == 5);
}

[Fact]
public void MergesComparedEntries()
{
Assert.Equal(
5,
new LengthOf(
new Distinct<INumber>(
new ManyOf<IEnumerable<INumber>>(
new ManyOf<INumber>(
new NumberOf(1),
new NumberOf(2),
new NumberOf(3)
),
new ManyOf<INumber>(
new NumberOf(10),
new NumberOf(2),
new NumberOf(30)
)
),
(v1, v2) => v1.AsInt().Equals(v2.AsInt())
)
).Value()
);
}

[Fact]
public void MergesEntriesWithEnumCtor()
{
Expand Down

0 comments on commit 090b1fc

Please sign in to comment.