Skip to content

Commit

Permalink
Improve collection expressions usage (#626)
Browse files Browse the repository at this point in the history
  • Loading branch information
viceroypenguin authored Feb 13, 2024
1 parent 8adb9c7 commit c1ae626
Show file tree
Hide file tree
Showing 27 changed files with 159 additions and 228 deletions.
38 changes: 0 additions & 38 deletions Source/SuperLinq.Async/Partition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,42 +83,4 @@ static async ValueTask<TResult> Core(
return resultSelector(lookup[true], lookup[false]);
}
}

private static async ValueTask<TResult> PartitionImpl<TKey, TElement, TResult>(
IAsyncEnumerable<IAsyncGrouping<TKey, TElement>> source,
int count, TKey? key1, TKey? key2, TKey? key3, IEqualityComparer<TKey>? comparer,
Func<IAsyncEnumerable<TElement>, IAsyncEnumerable<TElement>, IAsyncEnumerable<TElement>, IAsyncEnumerable<IAsyncGrouping<TKey, TElement>>, TResult> resultSelector,
CancellationToken cancellationToken)
{
comparer ??= EqualityComparer<TKey>.Default;

List<IAsyncGrouping<TKey, TElement>>? etc = null;

var groups = new[]
{
AsyncEnumerable.Empty<TElement>(),
AsyncEnumerable.Empty<TElement>(),
AsyncEnumerable.Empty<TElement>(),
};

await foreach (var e in source.WithCancellation(cancellationToken).ConfigureAwait(false))
{
var i = count > 0 && comparer.Equals(e.Key, key1) ? 0
: count > 1 && comparer.Equals(e.Key, key2) ? 1
: count > 2 && comparer.Equals(e.Key, key3) ? 2
: -1;

if (i < 0)
{
etc ??= new List<IAsyncGrouping<TKey, TElement>>();
etc.Add(e);
}
else
{
groups[i] = e;
}
}

return resultSelector(groups[0], groups[1], groups[2], etc?.ToAsyncEnumerable() ?? AsyncEnumerable.Empty<IAsyncGrouping<TKey, TElement>>());
}
}
2 changes: 1 addition & 1 deletion Source/SuperLinq/Case.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static IEnumerable<TResult> Case<TValue, TResult>(
IDictionary<TValue, IEnumerable<TResult>> sources)
where TValue : notnull
{
return Case(selector, sources, Enumerable.Empty<TResult>());
return Case(selector, sources, []);
}

/// <summary>
Expand Down
6 changes: 3 additions & 3 deletions Source/SuperLinq/Collections/UpdatablePriorityQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ static UpdatablePriorityQueue()
/// </summary>
public UpdatablePriorityQueue()
{
_nodes = Array.Empty<(TElement, TPriority)>();
_nodes = [];
_priorityComparer = InitializeComparer(comparer: null);
_elementIndex = new(_elementComparer = EqualityComparer<TElement>.Default);
}
Expand Down Expand Up @@ -104,7 +104,7 @@ public UpdatablePriorityQueue(int initialCapacity)
/// </param>
public UpdatablePriorityQueue(IComparer<TPriority>? priorityComparer)
{
_nodes = Array.Empty<(TElement, TPriority)>();
_nodes = [];
_priorityComparer = InitializeComparer(priorityComparer);
_elementIndex = new(_elementComparer = EqualityComparer<TElement>.Default);
}
Expand All @@ -119,7 +119,7 @@ public UpdatablePriorityQueue(IComparer<TPriority>? priorityComparer)
/// </param>
public UpdatablePriorityQueue(IEqualityComparer<TElement>? elementComparer)
{
_nodes = Array.Empty<(TElement, TPriority)>();
_nodes = [];
_priorityComparer = InitializeComparer(comparer: null);
_elementComparer = elementComparer ?? EqualityComparer<TElement>.Default;
_elementIndex = new(_elementComparer);
Expand Down
2 changes: 1 addition & 1 deletion Source/SuperLinq/FullGroupJoin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ IEnumerable<TResult> Core(IEqualityComparer<TKey> comparer)
if (alookup.Contains(b.Key))
continue;
// We can skip the lookup because we are iterating over keys not found in the first sequence
yield return resultSelector(b.Key, Enumerable.Empty<TFirst>(), b);
yield return resultSelector(b.Key, [], b);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Source/SuperLinq/If.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public static partial class SuperEnumerable
/// </remarks>
public static IEnumerable<TResult> If<TResult>(Func<bool> condition, IEnumerable<TResult> thenSource)
{
return If(condition, thenSource, Enumerable.Empty<TResult>());
return If(condition, thenSource, []);
}

/// <summary>
Expand Down
37 changes: 0 additions & 37 deletions Source/SuperLinq/Partition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,41 +74,4 @@ public static TResult Partition<T, TResult>(
var lookup = source.ToLookup(predicate);
return resultSelector(lookup[true], lookup[false]);
}

private static TResult PartitionImpl<TKey, TElement, TResult>(
IEnumerable<IGrouping<TKey, TElement>> source,
int count, TKey? key1, TKey? key2, TKey? key3, IEqualityComparer<TKey>? comparer,
Func<IEnumerable<TElement>, IEnumerable<TElement>, IEnumerable<TElement>, IEnumerable<IGrouping<TKey, TElement>>, TResult> resultSelector)
{
comparer ??= EqualityComparer<TKey>.Default;

List<IGrouping<TKey, TElement>>? etc = null;

var groups = new[]
{
Enumerable.Empty<TElement>(),
Enumerable.Empty<TElement>(),
Enumerable.Empty<TElement>(),
};

foreach (var e in source)
{
var i = count > 0 && comparer.Equals(e.Key, key1) ? 0
: count > 1 && comparer.Equals(e.Key, key2) ? 1
: count > 2 && comparer.Equals(e.Key, key3) ? 2
: -1;

if (i < 0)
{
etc ??= new List<IGrouping<TKey, TElement>>();
etc.Add(e);
}
else
{
groups[i] = e;
}
}

return resultSelector(groups[0], groups[1], groups[2], etc ?? Enumerable.Empty<IGrouping<TKey, TElement>>());
}
}
2 changes: 1 addition & 1 deletion Source/SuperLinq/Sequence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public static IEnumerable<int> Sequence(int start, int stop, int step)
return Return(start);

if (Math.Sign((long)stop - start) != Math.Sign(step))
return Enumerable.Empty<int>();
return [];

return new SequenceIterator(start, step, (((long)stop - start) / step) + 1);
}
Expand Down
5 changes: 3 additions & 2 deletions Source/SuperLinq/Take.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ public static IEnumerable<TSource> Take<TSource>(IEnumerable<TSource> source, Ra
{
if (start.Value == 0 || (end.IsFromEnd && end.Value >= start.Value))
{
return Array.Empty<TSource>();
return [];
}
}
else if (!end.IsFromEnd)
{
return start.Value >= end.Value ? Array.Empty<TSource>()
return start.Value >= end.Value
? []
: TakeRangeIterator(source, start.Value, end.Value);
}

Expand Down
4 changes: 2 additions & 2 deletions Source/SuperLinq/ToDataTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,12 @@ public static TTable ToDataTable<T, TTable>(this IEnumerable<T> source, TTable t
return table;
}

private static IEnumerable<MemberInfo> PrepareMemberInfos<T>(ICollection<Expression<Func<T, object>>> expressions)
private static IEnumerable<MemberInfo> PrepareMemberInfos<T>(Expression<Func<T, object>>[] expressions)
{
//
// If no lambda expressions supplied then reflect them off the source element type.
//
if (expressions.Count == 0)
if (expressions.Length == 0)
{
return typeof(T).GetMembers(BindingFlags.Public | BindingFlags.Instance)
.Where(m => m.MemberType == MemberTypes.Field
Expand Down
8 changes: 4 additions & 4 deletions Tests/SuperLinq.Async.Test/AggregateByTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ await ts.AggregateBy(keySelector, seedSelector, func, comparer)
seedSelector: x => 0,
func: (x, y) => x + y,
comparer: null,
expected: Enumerable.Empty<KeyValuePair<int, int>>());
expected: []);

yield return WrapArgs(
source: Enumerable.Range(0, 10),
Expand Down Expand Up @@ -134,7 +134,7 @@ await ts.AggregateBy(keySelector, seedSelector, func, comparer)
});

static object?[] WrapArgs<TSource, TKey, TAccumulate>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, TAccumulate> seedSelector, Func<TAccumulate, TSource, TAccumulate> func, IEqualityComparer<TKey>? comparer, IEnumerable<KeyValuePair<TKey, TAccumulate>> expected)
=> new object?[] { source, keySelector, seedSelector, func, comparer, expected };
=> [source, keySelector, seedSelector, func, comparer, expected];
}

[Fact]
Expand All @@ -154,8 +154,8 @@ static IAsyncEnumerable<KeyValuePair<TKey, List<TSource>>> GroupBy<TSource, TKey
i => i % 2 == 0)
.ToDictionaryAsync(x => x.Key, x => x.Value);

Assert.True(oddsEvens[true].CollectionEqual(new[] { 2, 4, }));
Assert.True(oddsEvens[false].CollectionEqual(new[] { 1, 3, }));
Assert.True(oddsEvens[true].CollectionEqual([2, 4,]));
Assert.True(oddsEvens[false].CollectionEqual([1, 3,]));
}

[Fact]
Expand Down
12 changes: 9 additions & 3 deletions Tests/SuperLinq.Async.Test/CopyToTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;

namespace Test.Async;

Expand All @@ -9,10 +10,10 @@ public async Task NullArgumentTest()
{
_ = await Assert.ThrowsAsync<ArgumentNullException>(
"source",
async () => await default(IAsyncEnumerable<int>)!.CopyTo(Array.Empty<int>()));
async () => await default(IAsyncEnumerable<int>)!.CopyTo([]));
_ = await Assert.ThrowsAsync<ArgumentNullException>(
"source",
async () => await default(IAsyncEnumerable<int>)!.CopyTo(Array.Empty<int>(), 1));
async () => await default(IAsyncEnumerable<int>)!.CopyTo([], 1));
_ = await Assert.ThrowsAsync<ArgumentNullException>(
"list",
async () => await AsyncSeq<int>().CopyTo(default(int[])!));
Expand All @@ -26,10 +27,15 @@ public Task ThrowsOnNegativeIndex()
{
return Assert.ThrowsAsync<ArgumentOutOfRangeException>(
"index",
async () => await AsyncSeq<int>().CopyTo(Array.Empty<int>(), -1));
async () => await AsyncSeq<int>().CopyTo([], -1));
}

[Fact]
[SuppressMessage(
"Style",
"IDE0301:Simplify collection initialization",
Justification = "`[]` uses a list by default."
)]
public Task ThrowsOnTooMuchDataForArray()
{
return Assert.ThrowsAsync<IndexOutOfRangeException>(
Expand Down
2 changes: 1 addition & 1 deletion Tests/SuperLinq.Async.Test/SplitTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public async Task SplitWithComparerUptoMaxCount()
{
await using var sequence = Enumerable.Range(1, 10).AsTestingSequence();
var result = sequence.Split(2, EqualityComparer.Create<int>((x, y) => x % 2 == y % 2), 2);
await result.AssertSequenceEqual(new[] { 1 }, new[] { 3 }, Enumerable.Range(5, 6));
await result.AssertSequenceEqual([1], [3], Enumerable.Range(5, 6));
}

[Fact]
Expand Down
4 changes: 2 additions & 2 deletions Tests/SuperLinq.Test/AggregateByTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static void AggregateBy_HasExpectedOutput<TSource, TKey, TAccumulate>(
seedSelector: x => 0,
func: (x, y) => x + y,
comparer: null,
expected: Enumerable.Empty<KeyValuePair<int, int>>());
expected: []);

yield return WrapArgs(
source: Enumerable.Range(0, 10),
Expand Down Expand Up @@ -134,7 +134,7 @@ public static void AggregateBy_HasExpectedOutput<TSource, TKey, TAccumulate>(
});

static object?[] WrapArgs<TSource, TKey, TAccumulate>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, TAccumulate> seedSelector, Func<TAccumulate, TSource, TAccumulate> func, IEqualityComparer<TKey>? comparer, IEnumerable<KeyValuePair<TKey, TAccumulate>> expected)
=> new object?[] { source, keySelector, seedSelector, func, comparer, expected };
=> [source, keySelector, seedSelector, func, comparer, expected];
}

[Fact]
Expand Down
2 changes: 1 addition & 1 deletion Tests/SuperLinq.Test/BacksertTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public void BacksertIsLazy()
public void BacksertWithNegativeIndex()
{
_ = Assert.Throws<ArgumentOutOfRangeException>(() =>
new BreakingSequence<int>().Backsert(new[] { 97, 98, 99 }, -1));
new BreakingSequence<int>().Backsert([97, 98, 99], -1));
}

[Theory]
Expand Down
2 changes: 1 addition & 1 deletion Tests/SuperLinq.Test/BatchTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ private static IEnumerable<IList<T>> GetBatches<T>(
};

public static IEnumerable<object[]> GetEmptySequences() =>
GetBatchTestSequences(Enumerable.Empty<int>());
GetBatchTestSequences([]);

[Theory]
[MemberData(nameof(GetEmptySequences))]
Expand Down
16 changes: 10 additions & 6 deletions Tests/SuperLinq.Test/CopyToTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;

namespace Test;

Expand All @@ -11,16 +12,16 @@ public void NullArgumentTest()
{
_ = Assert.Throws<ArgumentNullException>(
"source",
() => default(IEnumerable<int>)!.CopyTo(Array.Empty<int>()));
() => default(IEnumerable<int>)!.CopyTo((int[])[]));
_ = Assert.Throws<ArgumentNullException>(
"source",
() => default(IEnumerable<int>)!.CopyTo((IList<int>)[]));
_ = Assert.Throws<ArgumentNullException>(
"source",
() => default(IEnumerable<int>)!.CopyTo(Array.Empty<int>(), 1));
() => default(IEnumerable<int>)!.CopyTo([], 1));
_ = Assert.Throws<ArgumentNullException>(
"source",
() => default(IEnumerable<int>)!.CopyTo(Array.Empty<int>().AsSpan()));
() => default(IEnumerable<int>)!.CopyTo([]));
_ = Assert.Throws<ArgumentNullException>(
"array",
() => Seq<int>().CopyTo(default(int[])!));
Expand All @@ -37,7 +38,7 @@ public void ThrowsOnNegativeIndex()
{
_ = Assert.Throws<ArgumentOutOfRangeException>(
"index",
() => Seq<int>().CopyTo(Array.Empty<int>(), -1));
() => Seq<int>().CopyTo([], -1));
}

[Fact]
Expand All @@ -52,9 +53,13 @@ public void ThrowsOnTooMuchDataForArray()
}

[Fact]
[SuppressMessage(
"Style",
"IDE0301:Simplify collection initialization",
Justification = "`[]` uses a list by default."
)]
public void ThrowsOnTooMuchDataForIListArray()
{
#pragma warning disable IDE0301 // Simplify collection initialization
_ = Assert.ThrowsAny<ArgumentException>(
() => Seq(1).CopyTo((IList<int>)Array.Empty<int>()));
_ = Assert.ThrowsAny<ArgumentException>(
Expand All @@ -63,7 +68,6 @@ public void ThrowsOnTooMuchDataForIListArray()
() => new List<int> { 1 }.AsEnumerable().CopyTo((IList<int>)Array.Empty<int>()));
_ = Assert.ThrowsAny<ArgumentException>(
() => new List<int> { 1 }.AsReadOnly().AsEnumerable().CopyTo((IList<int>)Array.Empty<int>()));
#pragma warning restore IDE0301 // Simplify collection initialization
}

[Fact]
Expand Down
2 changes: 1 addition & 1 deletion Tests/SuperLinq.Test/InsertTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public void InsertIsLazy()
public void InsertWithNegativeIndex()
{
_ = Assert.Throws<ArgumentOutOfRangeException>(() =>
new BreakingSequence<int>().Insert(new[] { 97, 98, 99 }, -1));
new BreakingSequence<int>().Insert([97, 98, 99], -1));
}

public static IEnumerable<object[]> GetSequences()
Expand Down
2 changes: 1 addition & 1 deletion Tests/SuperLinq.Test/InterleaveTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public void TestInterleaveTwoEmptySequences()
using var sequenceB = TestingSequence.Of<int>();

var result = sequenceA.Interleave(sequenceB);
Assert.Equal(Enumerable.Empty<int>(), result);
Assert.Equal([], result);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion Tests/SuperLinq.Test/SplitTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public void SplitWithComparerUptoMaxCount()
{
using var sequence = Enumerable.Range(1, 10).AsTestingSequence();
var result = sequence.Split(2, EqualityComparer.Create<int>((x, y) => x % 2 == y % 2), 2).ToList();
result.AssertSequenceEqual(new[] { 1 }, new[] { 3 }, Enumerable.Range(5, 6));
result.AssertSequenceEqual([1], [3], Enumerable.Range(5, 6));
}

[Fact]
Expand Down
Loading

0 comments on commit c1ae626

Please sign in to comment.