-
Notifications
You must be signed in to change notification settings - Fork 414
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
531fe71
commit 5205ea2
Showing
4 changed files
with
263 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,123 @@ | ||
#region License and Terms | ||
// MoreLINQ - Extensions to LINQ to Objects | ||
// Copyright (c) 2019 Leandro F. Vieira (leandromoh). 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; | ||
using NUnit.Framework; | ||
|
||
[TestFixture] | ||
public class IndexByTest | ||
{ | ||
[Test] | ||
public void IndexBySimpleTest() | ||
{ | ||
var source = new[] { "ana", "beatriz", "carla", "bob", "davi", "adriano", "angelo", "carlos" }; | ||
var result = source.IndexBy(x => x.First()); | ||
|
||
result.AssertSequenceEqual( | ||
KeyValuePair.Create(0, "ana" ), | ||
KeyValuePair.Create(0, "beatriz"), | ||
KeyValuePair.Create(0, "carla" ), | ||
KeyValuePair.Create(1, "bob" ), | ||
KeyValuePair.Create(0, "davi" ), | ||
KeyValuePair.Create(1, "adriano"), | ||
KeyValuePair.Create(2, "angelo" ), | ||
KeyValuePair.Create(1, "carlos" )); | ||
} | ||
|
||
[Test] | ||
public void IndexByWithSecondOccurenceImmediatelyAfterFirst() | ||
{ | ||
var result = "jaffer".IndexBy(c => c); | ||
|
||
result.AssertSequenceEqual( | ||
KeyValuePair.Create(0, 'j'), | ||
KeyValuePair.Create(0, 'a'), | ||
KeyValuePair.Create(0, 'f'), | ||
KeyValuePair.Create(1, 'f'), | ||
KeyValuePair.Create(0, 'e'), | ||
KeyValuePair.Create(0, 'r')); | ||
} | ||
|
||
[Test] | ||
public void IndexByWithEqualityComparer() | ||
{ | ||
var source = new[] { "a", "B", "c", "A", "b", "A" }; | ||
var result = source.IndexBy(c => c, StringComparer.OrdinalIgnoreCase); | ||
|
||
result.AssertSequenceEqual( | ||
KeyValuePair.Create(0, "a"), | ||
KeyValuePair.Create(0, "B"), | ||
KeyValuePair.Create(0, "c"), | ||
KeyValuePair.Create(1, "A"), | ||
KeyValuePair.Create(1, "b"), | ||
KeyValuePair.Create(2, "A")); | ||
} | ||
|
||
[Test] | ||
public void IndexByIsLazy() | ||
{ | ||
new BreakingSequence<string>().IndexBy(BreakingFunc.Of<string, char>()); | ||
} | ||
|
||
[Test] | ||
public void IndexByWithSomeNullKeys() | ||
{ | ||
var source = new[] { "foo", null, "bar", "baz", null, null, "baz", "bar", null, "foo" }; | ||
var result = source.IndexBy(c => c); | ||
|
||
const string @null = null; // type inference happiness | ||
result.AssertSequenceEqual( | ||
KeyValuePair.Create(0, "foo"), | ||
KeyValuePair.Create(0, @null), | ||
KeyValuePair.Create(0, "bar"), | ||
KeyValuePair.Create(0, "baz"), | ||
KeyValuePair.Create(1, @null), | ||
KeyValuePair.Create(2, @null), | ||
KeyValuePair.Create(1, "baz"), | ||
KeyValuePair.Create(1, "bar"), | ||
KeyValuePair.Create(3, @null), | ||
KeyValuePair.Create(1, "foo")); | ||
} | ||
|
||
[Test] | ||
public void IndexBytDoesNotIterateUnnecessaryElements() | ||
{ | ||
var source = MoreEnumerable.From(() => "ana", | ||
() => "beatriz", | ||
() => "carla", | ||
() => "bob", | ||
() => "davi", | ||
() => throw new TestException(), | ||
() => "angelo", | ||
() => "carlos"); | ||
|
||
var result = source.IndexBy(x => x.First()); | ||
|
||
result.Take(5).AssertSequenceEqual( | ||
KeyValuePair.Create(0, "ana" ), | ||
KeyValuePair.Create(0, "beatriz"), | ||
KeyValuePair.Create(0, "carla" ), | ||
KeyValuePair.Create(1, "bob" ), | ||
KeyValuePair.Create(0, "davi" )); | ||
|
||
Assert.Throws<TestException>(() => | ||
result.ElementAt(5)); | ||
} | ||
} | ||
} |
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 |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#region License and Terms | ||
// MoreLINQ - Extensions to LINQ to Objects | ||
// Copyright (c) 2019 Leandro F. Vieira (leandromoh). 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> | ||
/// Applies a key-generating function to each element of a sequence and | ||
/// returns a sequence that contains the elements of the original | ||
/// sequence as well its key and index inside the group of its key. | ||
/// </summary> | ||
/// <typeparam name="TSource">Type of the source sequence elements.</typeparam> | ||
/// <typeparam name="TKey">Type of the projected key.</typeparam> | ||
/// <param name="source">Source sequence.</param> | ||
/// <param name="keySelector"> | ||
/// Function that projects the key given an element in the source sequence.</param> | ||
/// <returns> | ||
/// A sequence of elements paired with their index within the key-group. | ||
/// The index is the key and the element is the value of the pair. | ||
/// </returns> | ||
|
||
public static IEnumerable<KeyValuePair<int, TSource>> | ||
IndexBy<TSource, TKey>( | ||
this IEnumerable<TSource> source, | ||
Func<TSource, TKey> keySelector) => | ||
source.IndexBy(keySelector, null); | ||
|
||
/// <summary> | ||
/// Applies a key-generating function to each element of a sequence and | ||
/// returns a sequence that contains the elements of the original | ||
/// sequence as well its key and index inside the group of its key. | ||
/// An additional parameter specifies a comparer to use for testing the | ||
/// equivalence of keys. | ||
/// </summary> | ||
/// <typeparam name="TSource">Type of the source sequence elements.</typeparam> | ||
/// <typeparam name="TKey">Type of the projected key.</typeparam> | ||
/// <param name="source">Source sequence.</param> | ||
/// <param name="keySelector"> | ||
/// Function that projects the key given an element in the source sequence.</param> | ||
/// <param name="comparer"> | ||
/// The equality comparer to use to determine whether or not keys are | ||
/// equal. If <c>null</c>, the default equality comparer for | ||
/// <typeparamref name="TSource"/> is used.</param> | ||
/// <returns> | ||
/// A sequence of elements paired with their index within the key-group. | ||
/// The index is the key and the element is the value of the pair. | ||
/// </returns> | ||
|
||
public static IEnumerable<KeyValuePair<int, TSource>> | ||
IndexBy<TSource, TKey>( | ||
this IEnumerable<TSource> source, | ||
Func<TSource, TKey> keySelector, | ||
IEqualityComparer<TKey> comparer) => | ||
from e in source.ScanBy(keySelector, k => (Index: -1, Item: default(TSource)), (s, k, e) => (s.Index + 1, e), comparer) | ||
select new KeyValuePair<int, TSource>(e.Value.Index, e.Value.Item); | ||
} | ||
} |
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