// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace System.Linq { public static partial class AsyncEnumerable { /// /// Produces the set intersection of two async-enumerable sequences by using the default equality comparer to compare values. /// /// The type of the elements of the input sequences. /// An async-enumerable sequence whose distinct elements that also appear in second will be returned. /// An async-enumerable sequence whose distinct elements that also appear in the first sequence will be returned. /// A sequence that contains the elements that form the set intersection of two sequences. /// or is null. public static IAsyncEnumerable Intersect(this IAsyncEnumerable first, IAsyncEnumerable second) => Intersect(first, second, comparer: null); /// /// Produces the set intersection of two async-enumerable sequences by using the specified equality comparer to compare values. /// /// The type of the elements of the input sequences. /// An async-enumerable sequence whose distinct elements that also appear in second will be returned. /// An async-enumerable sequence whose distinct elements that also appear in the first sequence will be returned. /// An equality comparer to compare values. /// A sequence that contains the elements that form the set intersection of two sequences. /// or is null. public static IAsyncEnumerable Intersect(this IAsyncEnumerable first, IAsyncEnumerable second, IEqualityComparer? comparer) { if (first == null) throw Error.ArgumentNull(nameof(first)); if (second == null) throw Error.ArgumentNull(nameof(second)); return Create(Core); async IAsyncEnumerator Core(CancellationToken cancellationToken) { var set = new Set(comparer); await foreach (var element in second.WithCancellation(cancellationToken).ConfigureAwait(false)) { set.Add(element); } await foreach (var element in first.WithCancellation(cancellationToken).ConfigureAwait(false)) { if (set.Remove(element)) { yield return element; } } } } } }