首頁 >後端開發 >C++ >如何在LINQ中執行完整的外部加入以根據ID合併兩個人列表?

如何在LINQ中執行完整的外部加入以根據ID合併兩個人列表?

DDD
DDD原創
2025-01-31 17:11:10108瀏覽

How to Perform a Full Outer Join in LINQ to Merge Two Lists of People Based on ID?

LINQ - 全外部聯接

問題:

給定兩個包含ID以及名字或姓氏的人員列表,執行全外部聯接以生成包含名字和姓氏的個人列表。

解答:

全外部聯接與其他聯接的不同之處在於,它包含來自兩個輸入列表的項,即使在另一個列表中沒有匹配的元素。 為此,我們可以利用FullOuterJoin擴展方法,其工作原理如下:

  1. 使用指定的鍵選擇器函數為兩個輸入列表創建查找表。
  2. 識別兩個查找表中的唯一鍵並將它們組合成一個集合。
  3. 遍歷鍵集,並為每個鍵從查找表中檢索相應的值。
  4. 利用投影函數生成每次迭代的所需結果。

更新後的代碼實現:

<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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn