首页 >后端开发 >C++ >如何使用LINQ在两个列表上执行完整的外部连接?

如何使用LINQ在两个列表上执行完整的外部连接?

Linda Hamilton
Linda Hamilton原创
2025-01-31 17:16:101016浏览

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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn