質問:
共通のキーフィールドに基づいて2つのオブジェクトリスト間で完全な接続を実行する方法。他のリストに対応する一致がない場合でも、両方のリストのすべてのレコードが結果に含まれるようにしますか?
答え:
public static IEnumerable FullOuterJoin(
this IEnumerable a,
IEnumerable b,
Func selectKeyA,
Func selectKeyB,
Func projection,
TA defaultA = default(TA),
TB defaultB = default(TB),
IEqualityComparer cmp = null)
{
cmp = cmp ?? EqualityComparer.Default;
var alookup = a.ToLookup(selectKeyA, cmp);
var blookup = b.ToLookup(selectKeyB, cmp);
var keys = new HashSet(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;
}
2。
と lastNames
の2つのリストがあります。完全な外部接続を実行するには、次のコードを使用できます。
var outourjoin = first in firstnames = from from from from from from from from from from from from from from from from from from from from from from from
LastNamesにLastに参加します
on first.id equals last.id
温度に
temp.defaultifempty()の最後から
[新規]を選択します
{
id = first!= null?:last.id、
firstName = first!= null?
インシデント= last!= null?name:string.empty
};
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
};
firstNames の最初のマッチングレコードに接続され、一致しない場合はデフォルト値に接続します。 への
temp ステートメントは、
lastnames に一致するレコードの一時的なコレクションを作成し、
defaultifempty()を適用して、ミスマッチレコードが含まれていることを確認できるようにします。 これにより、実際には、完全な意味での完全な外側の接続ではなく、左外の接続が実装されます。 完全な外部接続を実現するには、上記でカスタマイズされた
Fullouterjoin 拡張メソッドを使用する必要があります。
4。
完全な外部接続の予想出力は次のとおりです。
5。
ID FirstName LastName
-- --------- --------
1 John Doe
2 Sue
3 Smith
tolookup()操作にO(n)時間がかかり、その後の操作にはO(n m)時間が必要なためです。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3