Skip to content

Commit e8925dc

Browse files
committed
Split Zip into EquiZip, ZipLongest, ZipShortest
1 parent 236123a commit e8925dc

File tree

11 files changed

+3013
-2766
lines changed

11 files changed

+3013
-2766
lines changed

MoreLinq/EquiZip.g.cs

Lines changed: 824 additions & 0 deletions
Large diffs are not rendered by default.

MoreLinq/EquiZip.g.tt

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
<#@ template debug="false" hostspecific="false" language="C#" #>
2+
<#@ output extension=".cs" #>
3+
<#@ assembly name="System.Core" #>
4+
<#@ assembly name="System.Collections" #>
5+
<#@ import namespace="System.Globalization" #>
6+
<#@ import namespace="System.Linq" #>
7+
#region License and Terms
8+
// MoreLINQ - Extensions to LINQ to Objects
9+
// Copyright (c) 2019 Pierre Lando. All rights reserved.
10+
//
11+
// Licensed under the Apache License, Version 2.0 (the "License");
12+
// you may not use this file except in compliance with the License.
13+
// You may obtain a copy of the License at
14+
//
15+
// http://www.apache.org/licenses/LICENSE-2.0
16+
//
17+
// Unless required by applicable law or agreed to in writing, software
18+
// distributed under the License is distributed on an "AS IS" BASIS,
19+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20+
// See the License for the specific language governing permissions and
21+
// limitations under the License.
22+
#endregion
23+
24+
<#
25+
var ordinals = new[]
26+
{
27+
"",
28+
"first", "second", "third", "fourth",
29+
"fifth", "sixth", "seventh", "eighth"
30+
};
31+
32+
var overloads =
33+
Enumerable.Range(2, 7)
34+
.Select(argCount =>
35+
Enumerable.Range(1, argCount).Select(argPosition =>
36+
new
37+
{
38+
IsFirst = argPosition == 1,
39+
IsLast = argPosition == argCount,
40+
Name = ordinals[argPosition],
41+
Ordinal = ordinals[argPosition],
42+
Type = $"T{argPosition}",
43+
// Objects associated with the argument
44+
Enumerator = $"e{argPosition}",
45+
Value = $"v{argPosition}"
46+
}))
47+
.Select(args => args.ToList())
48+
.Select(args =>
49+
new
50+
{
51+
Arguments = args,
52+
TParams = string.Join(", ", args.Select(arg => arg.Type))
53+
});
54+
#>
55+
namespace MoreLinq
56+
{
57+
using System;
58+
using System.Collections.Generic;
59+
60+
static partial class MoreEnumerable
61+
{
62+
<# foreach (var o in overloads)
63+
{
64+
#>
65+
/// <summary>
66+
/// Returns a projection of tuples, where each tuple contains the N-th
67+
/// element from each of the input sequences. An exception is thrown
68+
/// if the input sequences are of different lengths.
69+
/// </summary>
70+
<# foreach (var arg in o.Arguments) { #>
71+
/// <typeparam name="<#=arg.Type#>">Type of elements in <#=arg.Name#> input sequence.</typeparam>
72+
<# } #>
73+
/// <typeparam name="TResult">Type of elements in result sequence.</typeparam>
74+
<# foreach (var arg in o.Arguments) { #>
75+
/// <param name="<#=arg.Name#>">The <#=arg.Ordinal#> source sequence.</param>
76+
<# } #>
77+
/// <param name="resultSelector">
78+
/// Function to apply to each tuple of elements.</param>
79+
/// <returns>
80+
/// A projection of tuples, where each tuple contains the N-th element
81+
/// from each of the argument sequences.</returns>
82+
/// <exception cref="InvalidOperationException">
83+
/// The input sequences are of different lengths.
84+
/// </exception>
85+
/// <remarks>
86+
/// This operator uses deferred execution and streams its results.
87+
/// </remarks>
88+
89+
public static IEnumerable<TResult> EquiZip<<#=o.TParams#>, TResult>(
90+
<# foreach (var arg in o.Arguments) { #>
91+
<#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#>,
92+
<# } #>
93+
Func<<#=o.TParams#>, TResult> resultSelector)
94+
{
95+
<# foreach (var arg in o.Arguments) { #>
96+
if (<#=arg.Name#> == null) throw new ArgumentNullException(nameof(<#=arg.Name#>));
97+
<# } #>
98+
if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector));
99+
100+
return _(); IEnumerable<TResult> _()
101+
{
102+
<# foreach (var arg in o.Arguments) { #>
103+
using var <#=arg.Enumerator#> = <#=arg.Name#>.GetEnumerator();
104+
<# } #>
105+
106+
for (;;)
107+
{
108+
if (<#=o.Arguments.First().Enumerator#>.MoveNext())
109+
{
110+
if (<# foreach (var arg in o.Arguments.Skip(1)) { #><#=arg.Enumerator#>.MoveNext()<#= arg.IsLast ? "" : " && " #><#}#>)
111+
yield return resultSelector(<# foreach (var arg in o.Arguments) { #><#=arg.Enumerator#>.Current<#= arg.IsLast ? "" : ", " #><#}#>);
112+
else
113+
break;
114+
}
115+
else
116+
{
117+
if (<# foreach (var arg in o.Arguments.Skip(1)) { #><#=arg.Enumerator#>.MoveNext()<#= arg.IsLast ? "" : " || " #><#}#>)
118+
break;
119+
else
120+
yield break;
121+
}
122+
}
123+
124+
throw new InvalidOperationException($"Sequences differ in length.");
125+
}
126+
}
127+
128+
/// <summary>
129+
/// Returns a sequence of tuples, where each tuple contains the N-th
130+
/// element from each of the input sequences. An exception is thrown
131+
/// if the input sequences are of different lengths.
132+
/// </summary>
133+
<# foreach (var arg in o.Arguments) { #>
134+
/// <typeparam name="<#=arg.Type#>">Type of elements in <#=arg.Name#> input sequence.</typeparam>
135+
<# } #>
136+
<# foreach (var arg in o.Arguments) { #>
137+
/// <param name="<#=arg.Name#>">The <#=arg.Ordinal#> source sequence.</param>
138+
<# } #>
139+
/// <returns>
140+
/// A sequence of tuples, where each tuple contains the N-th element
141+
/// from each of the argument sequences.</returns>
142+
/// <exception cref="InvalidOperationException">
143+
/// The input sequences are of different lengths.
144+
/// </exception>
145+
/// <remarks>
146+
/// This operator uses deferred execution and streams its results.
147+
/// </remarks>
148+
149+
public static IEnumerable<(<#=o.TParams#>)> EquiZip<<#=o.TParams#>>(
150+
<# foreach (var arg in o.Arguments) { #>
151+
<#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#><#= arg.IsLast ? ")" : "," #>
152+
<# } #>
153+
{
154+
return EquiZip(
155+
<# foreach (var arg in o.Arguments) { #>
156+
<#=arg.Name#>,
157+
<# } #>
158+
ValueTuple.Create);
159+
}
160+
161+
<# } #>
162+
}
163+
}

MoreLinq/Extensions.g.cs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,6 +1343,7 @@ public static partial class EquiZipExtension
13431343
/// <remarks>
13441344
/// This operator uses deferred execution and streams its results.
13451345
/// </remarks>
1346+
13461347
public static IEnumerable<(T1, T2)> EquiZip<T1, T2>(
13471348
this IEnumerable<T1> first,
13481349
IEnumerable<T2> second)
@@ -1368,6 +1369,7 @@ public static partial class EquiZipExtension
13681369
/// <remarks>
13691370
/// This operator uses deferred execution and streams its results.
13701371
/// </remarks>
1372+
13711373
public static IEnumerable<(T1, T2, T3)> EquiZip<T1, T2, T3>(
13721374
this IEnumerable<T1> first,
13731375
IEnumerable<T2> second,
@@ -1423,6 +1425,7 @@ public static IEnumerable<TResult> EquiZip<T1, T2, TResult>(
14231425
/// <remarks>
14241426
/// This operator uses deferred execution and streams its results.
14251427
/// </remarks>
1428+
14261429
public static IEnumerable<(T1, T2, T3, T4)> EquiZip<T1, T2, T3, T4>(
14271430
this IEnumerable<T1> first,
14281431
IEnumerable<T2> second,
@@ -1485,6 +1488,7 @@ public static IEnumerable<TResult> EquiZip<T1, T2, T3, TResult>(
14851488
/// <remarks>
14861489
/// This operator uses deferred execution and streams its results.
14871490
/// </remarks>
1491+
14881492
public static IEnumerable<(T1, T2, T3, T4, T5)> EquiZip<T1, T2, T3, T4, T5>(
14891493
this IEnumerable<T1> first,
14901494
IEnumerable<T2> second,
@@ -1553,6 +1557,7 @@ public static IEnumerable<TResult> EquiZip<T1, T2, T3, T4, TResult>(
15531557
/// <remarks>
15541558
/// This operator uses deferred execution and streams its results.
15551559
/// </remarks>
1560+
15561561
public static IEnumerable<(T1, T2, T3, T4, T5, T6)> EquiZip<T1, T2, T3, T4, T5, T6>(
15571562
this IEnumerable<T1> first,
15581563
IEnumerable<T2> second,
@@ -1627,6 +1632,7 @@ public static IEnumerable<TResult> EquiZip<T1, T2, T3, T4, T5, TResult>(
16271632
/// <remarks>
16281633
/// This operator uses deferred execution and streams its results.
16291634
/// </remarks>
1635+
16301636
public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> EquiZip<T1, T2, T3, T4, T5, T6, T7>(
16311637
this IEnumerable<T1> first,
16321638
IEnumerable<T2> second,
@@ -1707,6 +1713,7 @@ public static IEnumerable<TResult> EquiZip<T1, T2, T3, T4, T5, T6, TResult>(
17071713
/// <remarks>
17081714
/// This operator uses deferred execution and streams its results.
17091715
/// </remarks>
1716+
17101717
public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> EquiZip<T1, T2, T3, T4, T5, T6, T7, T8>(
17111718
this IEnumerable<T1> first,
17121719
IEnumerable<T2> second,
@@ -7165,6 +7172,7 @@ public static partial class ZipLongestExtension
71657172
/// <remarks>
71667173
/// This operator uses deferred execution and streams its results.
71677174
/// </remarks>
7175+
71687176
public static IEnumerable<(T1, T2)> ZipLongest<T1, T2>(
71697177
this IEnumerable<T1> first,
71707178
IEnumerable<T2> second)
@@ -7189,12 +7197,12 @@ public static partial class ZipLongestExtension
71897197
/// <remarks>
71907198
/// This operator uses deferred execution and streams its results.
71917199
/// </remarks>
7200+
71927201
public static IEnumerable<(T1, T2, T3)> ZipLongest<T1, T2, T3>(
71937202
this IEnumerable<T1> first,
71947203
IEnumerable<T2> second,
71957204
IEnumerable<T3> third)
71967205
=> MoreEnumerable.ZipLongest(first, second, third);
7197-
71987206
/// <summary>
71997207
/// Returns a projection of tuples, where each tuple contains the N-th
72007208
/// element from each of the input sequences. The resulting sequence
@@ -7215,6 +7223,7 @@ public static partial class ZipLongestExtension
72157223
/// <remarks>
72167224
/// This operator uses deferred execution and streams its results.
72177225
/// </remarks>
7226+
72187227
public static IEnumerable<TResult> ZipLongest<T1, T2, TResult>(
72197228
this IEnumerable<T1> first,
72207229
IEnumerable<T2> second,
@@ -7242,6 +7251,7 @@ public static IEnumerable<TResult> ZipLongest<T1, T2, TResult>(
72427251
/// <remarks>
72437252
/// This operator uses deferred execution and streams its results.
72447253
/// </remarks>
7254+
72457255
public static IEnumerable<(T1, T2, T3, T4)> ZipLongest<T1, T2, T3, T4>(
72467256
this IEnumerable<T1> first,
72477257
IEnumerable<T2> second,
@@ -7271,6 +7281,7 @@ public static IEnumerable<TResult> ZipLongest<T1, T2, TResult>(
72717281
/// <remarks>
72727282
/// This operator uses deferred execution and streams its results.
72737283
/// </remarks>
7284+
72747285
public static IEnumerable<TResult> ZipLongest<T1, T2, T3, TResult>(
72757286
this IEnumerable<T1> first,
72767287
IEnumerable<T2> second,
@@ -7301,6 +7312,7 @@ public static IEnumerable<TResult> ZipLongest<T1, T2, T3, TResult>(
73017312
/// <remarks>
73027313
/// This operator uses deferred execution and streams its results.
73037314
/// </remarks>
7315+
73047316
public static IEnumerable<(T1, T2, T3, T4, T5)> ZipLongest<T1, T2, T3, T4, T5>(
73057317
this IEnumerable<T1> first,
73067318
IEnumerable<T2> second,
@@ -7333,6 +7345,7 @@ public static IEnumerable<TResult> ZipLongest<T1, T2, T3, TResult>(
73337345
/// <remarks>
73347346
/// This operator uses deferred execution and streams its results.
73357347
/// </remarks>
7348+
73367349
public static IEnumerable<TResult> ZipLongest<T1, T2, T3, T4, TResult>(
73377350
this IEnumerable<T1> first,
73387351
IEnumerable<T2> second,
@@ -7366,6 +7379,7 @@ public static IEnumerable<TResult> ZipLongest<T1, T2, T3, T4, TResult>(
73667379
/// <remarks>
73677380
/// This operator uses deferred execution and streams its results.
73687381
/// </remarks>
7382+
73697383
public static IEnumerable<(T1, T2, T3, T4, T5, T6)> ZipLongest<T1, T2, T3, T4, T5, T6>(
73707384
this IEnumerable<T1> first,
73717385
IEnumerable<T2> second,
@@ -7401,6 +7415,7 @@ public static IEnumerable<TResult> ZipLongest<T1, T2, T3, T4, TResult>(
74017415
/// <remarks>
74027416
/// This operator uses deferred execution and streams its results.
74037417
/// </remarks>
7418+
74047419
public static IEnumerable<TResult> ZipLongest<T1, T2, T3, T4, T5, TResult>(
74057420
this IEnumerable<T1> first,
74067421
IEnumerable<T2> second,
@@ -7437,6 +7452,7 @@ public static IEnumerable<TResult> ZipLongest<T1, T2, T3, T4, T5, TResult>(
74377452
/// <remarks>
74387453
/// This operator uses deferred execution and streams its results.
74397454
/// </remarks>
7455+
74407456
public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> ZipLongest<T1, T2, T3, T4, T5, T6, T7>(
74417457
this IEnumerable<T1> first,
74427458
IEnumerable<T2> second,
@@ -7475,6 +7491,7 @@ public static IEnumerable<TResult> ZipLongest<T1, T2, T3, T4, T5, TResult>(
74757491
/// <remarks>
74767492
/// This operator uses deferred execution and streams its results.
74777493
/// </remarks>
7494+
74787495
public static IEnumerable<TResult> ZipLongest<T1, T2, T3, T4, T5, T6, TResult>(
74797496
this IEnumerable<T1> first,
74807497
IEnumerable<T2> second,
@@ -7514,6 +7531,7 @@ public static IEnumerable<TResult> ZipLongest<T1, T2, T3, T4, T5, T6, TResult>(
75147531
/// <remarks>
75157532
/// This operator uses deferred execution and streams its results.
75167533
/// </remarks>
7534+
75177535
public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> ZipLongest<T1, T2, T3, T4, T5, T6, T7, T8>(
75187536
this IEnumerable<T1> first,
75197537
IEnumerable<T2> second,
@@ -7555,6 +7573,7 @@ public static IEnumerable<TResult> ZipLongest<T1, T2, T3, T4, T5, T6, TResult>(
75557573
/// <remarks>
75567574
/// This operator uses deferred execution and streams its results.
75577575
/// </remarks>
7576+
75587577
public static IEnumerable<TResult> ZipLongest<T1, T2, T3, T4, T5, T6, T7, TResult>(
75597578
this IEnumerable<T1> first,
75607579
IEnumerable<T2> second,
@@ -7598,6 +7617,7 @@ public static IEnumerable<TResult> ZipLongest<T1, T2, T3, T4, T5, T6, T7, TResul
75987617
/// <remarks>
75997618
/// This operator uses deferred execution and streams its results.
76007619
/// </remarks>
7620+
76017621
public static IEnumerable<TResult> ZipLongest<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(
76027622
this IEnumerable<T1> first,
76037623
IEnumerable<T2> second,
@@ -7674,7 +7694,6 @@ public static partial class ZipShortestExtension
76747694
IEnumerable<T2> second,
76757695
IEnumerable<T3> third)
76767696
=> MoreEnumerable.ZipShortest(first, second, third);
7677-
76787697
/// <summary>
76797698
/// Returns a projection of tuples, where each tuple contains the N-th
76807699
/// element from each of the input sequences. The resulting sequence

0 commit comments

Comments
 (0)