首頁 > 後端開發 > C++ > 如何使用LINQ在兩個列表上執行完整的外部連接?

如何使用LINQ在兩個列表上執行完整的外部連接?

Linda Hamilton
發布: 2025-01-31 17:16:10
原創
921 人瀏覽過

How to Perform a Full Outer Join on Two Lists Using LINQ?

LINQ - 全外部聯接

問題:

如何使用LINQ對兩個對象列表執行全外部聯接,即使列表中某些對象並非所有屬性都存在?

說明:

  • 內部聯接:聯接兩個列表中具有對應鍵的元素,排除沒有對應元素的元素。
  • 外部聯接(左聯接):包括左側列表中的元素,即使右側列表中不存在對應元素。
  • 全外部聯接:包括兩個列表中的元素,無論它們在另一個列表中是否有對應元素。

實現:

以下代碼提供了一種執行全外部聯接的通用擴展方法:

<code class="language-csharp">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,
    TA defaultA = default(TA),
    TB defaultB = default(TB),
    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
               from xa in alookup[key].DefaultIfEmpty(defaultA)
               from xb in blookup[key].DefaultIfEmpty(defaultB)
               select projection(xa, xb, key);

    return join;
}</code>
登入後複製

此方法採用以下參數:

  • 要聯接的兩個列表 a 和 b。
  • 鍵選擇函數 selectKeyA 和 selectKeyB,指定 a 和 b 中對象的哪個屬性應用作聯接鍵。
  • 投影函數 projection,指定如何將聯接的元素轉換為結果類型 TResult。
  • 可選的默認值 defaultA 和 defaultB,如果對於給定鍵在另一個列表中不存在對應元素,則使用這些值。
  • 可選的鍵比較器 cmp,用於指定自定義鍵相等比較。

用法:

要使用此擴展方法,只需在第一個列表 a 上調用它:

<code class="language-csharp">var join = a.FullOuterJoin(b,
    a => a.ID,
    b => b.ID,
    (a, b, id) => new
    {
        id = a != null ? a.ID : b.ID,
        firstname = a != null ? a.Name : string.Empty,
        surname = b != null ? b.Name : string.Empty
    });</code>
登入後複製

這將產生所需輸出:

<code>ID  FirstName  LastName
--  ---------  --------
1   John       Doe
2   Sue        NULL
3   NULL       Smith</code>
登入後複製

以上是如何使用LINQ在兩個列表上執行完整的外部連接?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板