-
Notifications
You must be signed in to change notification settings - Fork 419
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is a squashed merge of PR #1037 that partially addresses #125. --------- Co-authored-by: Atif Aziz <code@raboof.com>
- Loading branch information
Showing
10 changed files
with
232 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#region License and Terms | ||
// MoreLINQ - Extensions to LINQ to Objects | ||
// Copyright (c) 2023 Julien Aspirot. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
#endregion | ||
|
||
namespace MoreLinq.Test | ||
{ | ||
using System.Collections.Generic; | ||
using NUnit.Framework; | ||
using Delegate = Delegating.Delegate; | ||
|
||
[TestFixture] | ||
public class DuplicatesTest | ||
{ | ||
[Test] | ||
public void Duplicates_IsLazy() | ||
{ | ||
_ = new BreakingSequence<object>().Duplicates(); | ||
} | ||
|
||
[Test] | ||
public void Streams_Duplicates_As_They_Are_Discovered() | ||
{ | ||
static IEnumerable<string> Source() | ||
{ | ||
yield return "DUPLICATED_STRING"; | ||
yield return "DUPLICATED_STRING"; | ||
throw new TestException(); | ||
} | ||
|
||
using var source = Source().AsTestingSequence(); | ||
|
||
var results = source.Duplicates().Take(1).ToArray(); | ||
|
||
Assert.That(results, Is.EqualTo(new[] { "DUPLICATED_STRING" })); | ||
} | ||
|
||
[Test] | ||
public void Sequence_Without_Duplicates_Returns_Empty_Sequence() | ||
{ | ||
using var input = TestingSequence.Of("FirstElement", "SecondElement", "ThirdElement"); | ||
|
||
var results = input.Duplicates().ToArray(); | ||
|
||
Assert.That(results, Is.Empty); | ||
} | ||
|
||
[Test] | ||
public void Sequence_With_Duplicates_Returns_Duplicates() | ||
{ | ||
using var input = | ||
TestingSequence.Of("FirstElement", | ||
"DUPLICATED_STRING", | ||
"DUPLICATED_STRING", | ||
"DUPLICATED_STRING", | ||
"ThirdElement"); | ||
|
||
var results = input.Duplicates().ToArray(); | ||
|
||
Assert.That(results, Contains.Item("DUPLICATED_STRING")); | ||
Assert.That(results, Has.Exactly(1).Items); | ||
} | ||
|
||
[Test] | ||
public void Sequence_With_Multiple_Duplicates_Returns_One_Instance_Of_Each_Duplicates() | ||
{ | ||
using var input = | ||
TestingSequence.Of("FirstElement", | ||
"DUPLICATED_STRING", | ||
"DUPLICATED_STRING", | ||
"DUPLICATED_STRING", | ||
"ThirdElement", | ||
"SECOND_DUPLICATED_STRING", | ||
"SECOND_DUPLICATED_STRING"); | ||
|
||
var results = input.Duplicates().ToArray(); | ||
|
||
Assert.That(results, Contains.Item("DUPLICATED_STRING")); | ||
Assert.That(results, Contains.Item("SECOND_DUPLICATED_STRING")); | ||
Assert.That(results, Has.Exactly(2).Items); | ||
} | ||
|
||
[Test] | ||
public void Sequence_With_Duplicates_But_Using_Comparer_That_Always_Return_False_Returns_Empty_Sequence() | ||
{ | ||
using var input = TestingSequence.Of("DUPLICATED_STRING", "DUPLICATED_STRING", "DUPLICATED_STRING"); | ||
|
||
var results = input.Duplicates(Delegate.EqualityComparer((_, _) => false, (string _) => 0)); | ||
|
||
Assert.That(results, Is.Empty); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
#region License and Terms | ||
// MoreLINQ - Extensions to LINQ to Objects | ||
// Copyright (c) 2023 Julien Aspirot. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
#endregion | ||
|
||
namespace MoreLinq | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
static partial class MoreEnumerable | ||
{ | ||
/// <summary> | ||
/// Returns all duplicate elements of the given source. | ||
/// </summary> | ||
/// <param name="source">The source sequence.</param> | ||
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam> | ||
/// <exception cref="ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception> | ||
/// <returns>All elements that are duplicated.</returns> | ||
/// <remarks>This operator uses deferred execution and streams its results.</remarks> | ||
|
||
public static IEnumerable<TSource> Duplicates<TSource>(this IEnumerable<TSource> source) => | ||
Duplicates(source, null); | ||
|
||
/// <summary> | ||
/// Returns all duplicate elements of the given source, using the specified equality | ||
/// comparer. | ||
/// </summary> | ||
/// <param name="source">The source sequence.</param> | ||
/// <param name="comparer"> | ||
/// The equality comparer to use to determine whether one <typeparamref name="TSource"/> | ||
/// equals another. If <see langword="null"/>, the default equality comparer for | ||
/// <typeparamref name="TSource"/> is used.</param> | ||
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam> | ||
/// <exception cref="ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception> | ||
/// <returns>All elements that are duplicated.</returns> | ||
/// <remarks>This operator uses deferred execution and streams its results.</remarks> | ||
|
||
public static IEnumerable<TSource> Duplicates<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource>? comparer) | ||
{ | ||
if (source is null) throw new ArgumentNullException(nameof(source)); | ||
|
||
return from e in source.ScanBy(static e => e, | ||
static _ => 0, | ||
static (count, _, _) => unchecked(Math.Min(count + 1, 3)), | ||
comparer) | ||
where e.Value is 2 | ||
select e.Key; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ | |
- CountDown | ||
- Consume | ||
- DistinctBy | ||
- Duplicates | ||
- EndsWith | ||
- EquiZip | ||
- Evaluate | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,6 @@ | ||
#nullable enable | ||
MoreLinq.Extensions.DuplicatesExtension | ||
static MoreLinq.Extensions.DuplicatesExtension.Duplicates<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source) -> System.Collections.Generic.IEnumerable<TSource>! | ||
static MoreLinq.Extensions.DuplicatesExtension.Duplicates<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source, System.Collections.Generic.IEqualityComparer<TSource>? comparer) -> System.Collections.Generic.IEnumerable<TSource>! | ||
static MoreLinq.MoreEnumerable.Duplicates<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source) -> System.Collections.Generic.IEnumerable<TSource>! | ||
static MoreLinq.MoreEnumerable.Duplicates<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source, System.Collections.Generic.IEqualityComparer<TSource>? comparer) -> System.Collections.Generic.IEnumerable<TSource>! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,6 @@ | ||
#nullable enable | ||
MoreLinq.Extensions.DuplicatesExtension | ||
static MoreLinq.Extensions.DuplicatesExtension.Duplicates<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source) -> System.Collections.Generic.IEnumerable<TSource>! | ||
static MoreLinq.Extensions.DuplicatesExtension.Duplicates<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source, System.Collections.Generic.IEqualityComparer<TSource>? comparer) -> System.Collections.Generic.IEnumerable<TSource>! | ||
static MoreLinq.MoreEnumerable.Duplicates<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source) -> System.Collections.Generic.IEnumerable<TSource>! | ||
static MoreLinq.MoreEnumerable.Duplicates<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source, System.Collections.Generic.IEqualityComparer<TSource>? comparer) -> System.Collections.Generic.IEnumerable<TSource>! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,6 @@ | ||
#nullable enable | ||
MoreLinq.Extensions.DuplicatesExtension | ||
static MoreLinq.Extensions.DuplicatesExtension.Duplicates<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source) -> System.Collections.Generic.IEnumerable<TSource>! | ||
static MoreLinq.Extensions.DuplicatesExtension.Duplicates<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source, System.Collections.Generic.IEqualityComparer<TSource>? comparer) -> System.Collections.Generic.IEnumerable<TSource>! | ||
static MoreLinq.MoreEnumerable.Duplicates<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source) -> System.Collections.Generic.IEnumerable<TSource>! | ||
static MoreLinq.MoreEnumerable.Duplicates<TSource>(this System.Collections.Generic.IEnumerable<TSource>! source, System.Collections.Generic.IEqualityComparer<TSource>? comparer) -> System.Collections.Generic.IEnumerable<TSource>! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters