ホームページ >バックエンド開発 >C++ >LINQで完全な外側結合を実行する方法は?

LINQで完全な外側結合を実行する方法は?

Patricia Arquette
Patricia Arquetteオリジナル
2025-01-31 17:21:13803ブラウズ

How to Perform a Full Outer Join in LINQ?

linq -outer outer connection

質問:

公開キーフィールドに基づいて2つのオブジェクト間の完全な接続を実行して、2つのリストのすべてのレコードが別のリストに対応する一致アイテムが含まれていなくても。

回答:

1。外部全体に接続されたカスタム拡張メソッド

LINQで外側の接続を実現するために、以下に示すようにカスタム拡張方法を定義できます。

2。を実装します 提供されている例には、2つのリストがあります:

。外側の接続を実行するには、次のコードを使用できます。
<code class="language-csharp">public 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>

3。説明

このコードは左の外部接続を使用し、

の各レコードは、一致するアイテムが見つからない場合、接続がデフォルト値に接続されています。 firstNamesこのステートメントは、lastNamesマッチングレコードの一時的なコレクションを作成し、

を適用して、不満なレコードが含まれていることを確認することができます。 これにより、実際には、完全な意味での完全な接続ではなく、左の外部接続が実現されます。 外側の接続を実現するには、上記のカスタマイズされた
<code class="language-csharp">var outerJoin = from first in firstNames
                join last in lastNames
                on first.ID equals last.ID
                into temp
                from last in temp.DefaultIfEmpty()
                select new
                {
                    id = first != null ? first.ID : last.ID,
                    firstname = first != null ? first.Name : string.Empty,
                    surname = last != null ? last.Name : string.Empty
                };</code>
拡張方法を使用する必要があります。

4。出力を期待

firstNames外側の接続の予想出力は次のとおりです。 lastNames into temp5。定義されたデフォルト値lastNames DefaultIfEmpty()拡張法により、不十分なレコードのデフォルト値を指定できます。この例では、不十分な名前のFullOuterJoinを指​​定し、非一致IDの負の整数を指定します。

6。パフォーマンスの注意事項

外部接続全体の実行時間はo(n m)で、nとmは2つの入力リストの長さです。これは、

操作にはO(n)時間が必要であり、その後の操作にはO(n m)時間が必要なためです。
<code>ID  FirstName  LastName
--  ---------  --------
1   John       Doe
2   Sue        
3             Smith</code>

7。linq実装

外側の接続全体のこの実装は現在、LINQ標準の一部ではありませんが、将来のバージョンに含めることをお勧めします。 標準のLINQは外部接続を直接サポートせず、それを達成するためにカスタマイズする必要があります。 string.Empty

以上がLINQで完全な外側結合を実行する方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。