Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Revert "Revert "Add another Zip IEnumerable<T> extension method (#26582)"" #35595

Merged
merged 2 commits into from
Feb 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/System.Linq.Queryable/ref/System.Linq.Queryable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ public static partial class Queryable
public static System.Linq.IQueryable<TSource> Union<TSource>(this System.Linq.IQueryable<TSource> source1, System.Collections.Generic.IEnumerable<TSource> source2, System.Collections.Generic.IEqualityComparer<TSource> comparer) { throw null; }
public static System.Linq.IQueryable<TSource> Where<TSource>(this System.Linq.IQueryable<TSource> source, System.Linq.Expressions.Expression<System.Func<TSource, bool>> predicate) { throw null; }
public static System.Linq.IQueryable<TSource> Where<TSource>(this System.Linq.IQueryable<TSource> source, System.Linq.Expressions.Expression<System.Func<TSource, int, bool>> predicate) { throw null; }
public static System.Linq.IQueryable<(TFirst First, TSecond Second)> Zip<TFirst, TSecond>(this System.Linq.IQueryable<TFirst> source1, System.Collections.Generic.IEnumerable<TSecond> source2) { throw null; }
public static System.Linq.IQueryable<TResult> Zip<TFirst, TSecond, TResult>(this System.Linq.IQueryable<TFirst> source1, System.Collections.Generic.IEnumerable<TSecond> source2, System.Linq.Expressions.Expression<System.Func<TFirst, TSecond, TResult>> resultSelector) { throw null; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,13 @@ public static MethodInfo Where_Index_TSource_2(Type TSource) =>
(s_Where_Index_TSource_2 = new Func<IQueryable<object>, Expression<Func<object, int, bool>>, IQueryable<object>>(Queryable.Where).GetMethodInfo().GetGenericMethodDefinition()))
.MakeGenericMethod(TSource);

private static MethodInfo s_Zip_TFirst_TSecond_2;

public static MethodInfo Zip_TFirst_TSecond_2(Type TFirst, Type TSecond) =>
(s_Zip_TFirst_TSecond_2 ??
(s_Zip_TFirst_TSecond_2 = new Func<IQueryable<object>, IEnumerable<object>, IQueryable<ValueTuple<object, object>>>(Queryable.Zip).GetMethodInfo().GetGenericMethodDefinition()))
.MakeGenericMethod(TFirst, TSecond);

private static MethodInfo s_Zip_TFirst_TSecond_TResult_3;

public static MethodInfo Zip_TFirst_TSecond_TResult_3(Type TFirst, Type TSecond, Type TResult) =>
Expand Down Expand Up @@ -866,4 +873,4 @@ public static MethodInfo Prepend_TSource_2(Type TSource) =>
(s_Prepend_TSource_2 = new Func<IQueryable<object>, object, IQueryable<object>>(Queryable.Prepend).GetMethodInfo().GetGenericMethodDefinition()))
.MakeGenericMethod(TSource);
}
}
}
19 changes: 19 additions & 0 deletions src/System.Linq.Queryable/src/System/Linq/Queryable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,25 @@ public static IQueryable<TSource> Concat<TSource>(this IQueryable<TSource> sourc
));
}

public static IQueryable<(TFirst First, TSecond Second)> Zip<TFirst, TSecond>(this IQueryable<TFirst> source1, IEnumerable<TSecond> source2)
{
if (source1 == null)
{
throw Error.ArgumentNull(nameof(source1));
}

if (source2 == null)
{
throw Error.ArgumentNull(nameof(source2));
}

return source1.Provider.CreateQuery<(TFirst, TSecond)>(
Expression.Call(
null,
CachedReflectionInfo.Zip_TFirst_TSecond_2(typeof(TFirst), typeof(TSecond)),
source1.Expression, GetSourceExpression(source2)));
}

public static IQueryable<TResult> Zip<TFirst, TSecond, TResult>(this IQueryable<TFirst> source1, IEnumerable<TSecond> source2, Expression<Func<TFirst, TSecond, TResult>> resultSelector)
{
if (source1 == null)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ProjectGuid>{7B88D79B-B799-4116-A7D0-AED572540CD4}</ProjectGuid>
<Configurations>netcoreapp-Debug;netcoreapp-Release;netstandard-Debug;netstandard-Release</Configurations>
Expand All @@ -7,6 +7,7 @@
<Compile Include="AppendPrependTests.cs" />
<Compile Include="TakeLastTests.cs" />
<Compile Include="SkipLastTests.cs" />
<Compile Include="ZipTests.netcoreapp.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="AggregateTests.cs" />
Expand Down
2 changes: 1 addition & 1 deletion src/System.Linq.Queryable/tests/ZipTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace System.Linq.Tests
{
public class ZipTests : EnumerableBasedTests
public partial class ZipTests : EnumerableBasedTests
{
[Fact]
public void CorrectResults()
Expand Down
53 changes: 53 additions & 0 deletions src/System.Linq.Queryable/tests/ZipTests.netcoreapp.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Xunit;

namespace System.Linq.Tests
{
public partial class ZipTests
{
[Fact]
public void Zip2_CorrectResults()
{
int[] first = new int[] { 1, 2, 3 };
int[] second = new int[] { 2, 5, 9 };
var expected = new (int, int)[] { (1, 2), (2, 5), (3, 9) };
Assert.Equal(expected, first.AsQueryable().Zip(second.AsQueryable()));
}

[Fact]
public void Zip2_FirstIsNull()
{
IQueryable<int> first = null;
int[] second = new int[] { 2, 5, 9 };
AssertExtensions.Throws<ArgumentNullException>("source1", () => first.Zip(second.AsQueryable()));
}

[Fact]
public void Zip2_SecondIsNull()
{
int[] first = new int[] { 1, 2, 3 };
IQueryable<int> second = null;
AssertExtensions.Throws<ArgumentNullException>("source2", () => first.AsQueryable().Zip(second));
}

[Fact]
public void Zip2()
{
int count = (new int[] { 0, 1, 2 }).AsQueryable().Zip((new int[] { 10, 11, 12 }).AsQueryable()).Count();
Assert.Equal(3, count);
}

[Fact]
public void TupleNames()
{
int[] first = new int[] { 1 };
int[] second = new int[] { 2 };
var tuple = first.AsQueryable().Zip(second.AsQueryable()).First();
Assert.Equal(tuple.Item1, tuple.First);
Assert.Equal(tuple.Item2, tuple.Second);
}
}
}
1 change: 1 addition & 0 deletions src/System.Linq/ref/System.Linq.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ public static partial class Enumerable
public static System.Collections.Generic.IEnumerable<TSource> Union<TSource>(this System.Collections.Generic.IEnumerable<TSource> first, System.Collections.Generic.IEnumerable<TSource> second, System.Collections.Generic.IEqualityComparer<TSource> comparer) { throw null; }
public static System.Collections.Generic.IEnumerable<TSource> Where<TSource>(this System.Collections.Generic.IEnumerable<TSource> source, System.Func<TSource, bool> predicate) { throw null; }
public static System.Collections.Generic.IEnumerable<TSource> Where<TSource>(this System.Collections.Generic.IEnumerable<TSource> source, System.Func<TSource, int, bool> predicate) { throw null; }
public static System.Collections.Generic.IEnumerable<(TFirst First,TSecond Second)> Zip<TFirst, TSecond>(this System.Collections.Generic.IEnumerable<TFirst> first, System.Collections.Generic.IEnumerable<TSecond> second) { throw null; }
public static System.Collections.Generic.IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this System.Collections.Generic.IEnumerable<TFirst> first, System.Collections.Generic.IEnumerable<TSecond> second, System.Func<TFirst, TSecond, TResult> resultSelector) { throw null; }
}
public partial interface IGrouping<out TKey, out TElement> : System.Collections.Generic.IEnumerable<TElement>, System.Collections.IEnumerable
Expand Down
27 changes: 27 additions & 0 deletions src/System.Linq/src/System/Linq/Zip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,33 @@ public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerabl
return ZipIterator(first, second, resultSelector);
}

public static IEnumerable<(TFirst First, TSecond Second)> Zip<TFirst, TSecond>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second)
{
if (first is null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.first);
}

if (second is null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.second);
}

return ZipIterator(first, second);
}

private static IEnumerable<(TFirst, TSecond)> ZipIterator<TFirst, TSecond>(IEnumerable<TFirst> first, IEnumerable<TSecond> second)
{
using (IEnumerator<TFirst> e1 = first.GetEnumerator())
using (IEnumerator<TSecond> e2 = second.GetEnumerator())
{
while (e1.MoveNext() && e2.MoveNext())
{
yield return (e1.Current, e2.Current);
}
}
}

private static IEnumerable<TResult> ZipIterator<TFirst, TSecond, TResult>(IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
{
using (IEnumerator<TFirst> e1 = first.GetEnumerator())
Expand Down
3 changes: 2 additions & 1 deletion src/System.Linq/tests/System.Linq.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ProjectGuid>{7C70BB15-870B-4946-8098-625DACD645A6}</ProjectGuid>
<Configurations>netcoreapp-Debug;netcoreapp-Release;netstandard-Debug;netstandard-Release;uapaot-Debug;uapaot-Release</Configurations>
Expand All @@ -10,6 +10,7 @@
<Compile Include="OrderByTests.cs" />
<Compile Include="ToHashSetTests.cs" />
<Compile Include="SelectManyTests.netcoreapp.cs" />
<Compile Include="ZipTests.netcoreapp.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="AggregateTests.cs" />
Expand Down
4 changes: 1 addition & 3 deletions src/System.Linq/tests/ZipTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections;
using System.Collections.Generic;
using Xunit;

namespace System.Linq.Tests
{
public class ZipTests : EnumerableTests
public partial class ZipTests : EnumerableTests
{
[Fact]
public void ImplicitTypeParameters()
Expand Down
Loading