diff --git a/src/Yaapii.Atoms/Enumerable/Distinct.cs b/src/Yaapii.Atoms/Enumerable/Distinct.cs index c2c93a89..48f46ef6 100644 --- a/src/Yaapii.Atoms/Enumerable/Distinct.cs +++ b/src/Yaapii.Atoms/Enumerable/Distinct.cs @@ -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 @@ -43,13 +44,25 @@ public Distinct(params IEnumerable[] enumerables) : this( /// The distinct elements of one or multiple Enumerables. /// /// enumerables to get distinct elements from - public Distinct(IEnumerable> enumerables) : base(() => + public Distinct(IEnumerable> enumerables) : this( + enumerables, + (v1, v2) => v1.Equals(v2) + ) + { } + + /// + /// The distinct elements of one or multiple Enumerables. + /// + /// enumerables to get distinct elements from + /// comparison to evaluate distinction + public Distinct(IEnumerable> enumerables, Func comparison) : base(() => new LiveMany(() => new Enumerator.Distinct( new Mapped, IEnumerator>( (e) => e.GetEnumerator(), enumerables - ) + ), + comparison ) ), false @@ -73,5 +86,12 @@ public static class Distinct /// /// enumerables to get distinct elements from public static IEnumerable New(IEnumerable> enumerables) => new Distinct(enumerables); + + /// + /// The distinct elements of one or multiple Enumerables. + /// + /// enumerables to get distinct elements from + /// comparison to evaluate distinction + public static IEnumerable New(IEnumerable> enumerables, Func comparison) => new Distinct(enumerables, comparison); } } diff --git a/src/Yaapii.Atoms/Enumerator/Distinct.cs b/src/Yaapii.Atoms/Enumerator/Distinct.cs index 702f108c..7c1af100 100644 --- a/src/Yaapii.Atoms/Enumerator/Distinct.cs +++ b/src/Yaapii.Atoms/Enumerator/Distinct.cs @@ -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; @@ -34,17 +35,27 @@ namespace Yaapii.Atoms.Enumerator public sealed class Distinct : IEnumerator { private readonly IEnumerable> originals; + private readonly Func comparison; private readonly Queue> buffer = new Queue>(); private readonly List hits = new List(); /// /// Enumerator that only gives the distinct elements of multiple enumerators. /// - /// - public Distinct(IEnumerable> enumerators) + public Distinct(IEnumerable> enumerators) : this( + enumerators, + (v1, v2) => v1.Equals(v2) + ) + { } + + /// + /// Enumerator that only gives the distinct elements of multiple enumerators. + /// + public Distinct(IEnumerable> enumerators, Func comparison) { - originals = enumerators; - buffer = new Queue>(enumerators); + this.originals = enumerators; + this.comparison = comparison; + this.buffer = new Queue>(enumerators); } /// @@ -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(this.hits, v => comparison(v, this.buffer.Peek().Current)).Value())) { this.hits.Add(this.buffer.Peek().Current); break; diff --git a/tests/Yaapii.Atoms.Tests/Enumerable/DistinctTest.cs b/tests/Yaapii.Atoms.Tests/Enumerable/DistinctTest.cs index d0a816e7..9458da6d 100644 --- a/tests/Yaapii.Atoms.Tests/Enumerable/DistinctTest.cs +++ b/tests/Yaapii.Atoms.Tests/Enumerable/DistinctTest.cs @@ -22,6 +22,7 @@ using System.Collections.Generic; using Xunit; +using Yaapii.Atoms.Number; namespace Yaapii.Atoms.Enumerable.Tests { @@ -39,6 +40,31 @@ public void MergesEntries() ).Value() == 5); } + [Fact] + public void MergesComparedEntries() + { + Assert.Equal( + 5, + new LengthOf( + new Distinct( + new ManyOf>( + new ManyOf( + new NumberOf(1), + new NumberOf(2), + new NumberOf(3) + ), + new ManyOf( + new NumberOf(10), + new NumberOf(2), + new NumberOf(30) + ) + ), + (v1, v2) => v1.AsInt().Equals(v2.AsInt()) + ) + ).Value() + ); + } + [Fact] public void MergesEntriesWithEnumCtor() {