LINQ - 全外部聯接
問題:
給定兩個包含ID以及名字或姓氏的人員列表,執行全外部聯接以生成包含名字和姓氏的個人列表。
解答:
全外部聯接與其他聯接的不同之處在於,它包含來自兩個輸入列表的項,即使在另一個列表中沒有匹配的元素。 為此,我們可以利用FullOuterJoin
擴展方法,其工作原理如下:
更新後的代碼實現:
<code class="language-csharp">internal static class MyExtensions { internal static IEnumerable<TResult> FullOuterJoin<TA, TB, TKey, TResult>( this IEnumerable<TA> a, IEnumerable<TB> b, Func<TA, TKey> selectKeyA, Func<TB, TKey> selectKeyB, Func<TA, TB, TKey, TResult> projection, IEqualityComparer<TKey> cmp = null) { cmp = cmp ?? EqualityComparer<TKey>.Default; var alookup = a.ToLookup(selectKeyA, cmp); var blookup = b.ToLookup(selectKeyB, cmp); var keys = new HashSet<TKey>(alookup.Select(p => p.Key), cmp); keys.UnionWith(blookup.Select(p => p.Key)); var join = from key in keys let xa = alookup[key].DefaultIfEmpty(default(TA)) let xb = blookup[key].DefaultIfEmpty(default(TB)) select projection(xa.FirstOrDefault(), xb.FirstOrDefault(), key); return join; } }</code>
示例用法:
<code class="language-csharp">var ax = new[] { new { id = 1, name = "John" }, new { id = 2, name = "Sue" } }; var bx = new[] { new { id = 1, surname = "Doe" }, new { id = 3, surname = "Smith" } }; ax.FullOuterJoin(bx, a => a.id, b => b.id, (a, b, id) => new { a?.name, b?.surname, id }) .ToList().ForEach(Console.WriteLine);</code>
這段代碼將輸出以下結果:
<code>{ name = John, surname = Doe, id = 1 } { name = Sue, surname = , id = 2 } { name = , surname = Smith, id = 3 }</code>
This revised answer uses FirstOrDefault()
to handle the potential null values from DefaultIfEmpty()
more gracefully and directly outputs the name and surname, along with the ID, making the result clearer. The ?.
null-conditional operator prevents exceptions if a
or b
are null.
以上是如何在LINQ中執行完整的外部加入以根據ID合併兩個人列表?的詳細內容。更多資訊請關注PHP中文網其他相關文章!