首页 >后端开发 >C++ >如何在LINQ中执行完整的外部加入以根据ID合并两个人列表?

如何在LINQ中执行完整的外部加入以根据ID合并两个人列表?

DDD
DDD原创
2025-01-31 17:11:10109浏览

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