如何将两个列表解析为字典,其中的 id 属性都成为键?

Posted

技术标签:

【中文标题】如何将两个列表解析为字典,其中的 id 属性都成为键?【英文标题】:How to parse two list into a dictionary, where the id property in both becomes the key? 【发布时间】:2021-11-01 14:13:01 【问题描述】:

我似乎很难找到一种简单的方法将我的旧注册和新注册插入到格式如下的字典中

Dictionary<int, List<Registration>, List<Registration>>

第一个列表包含 oldReg,另一个包含新注册。 它们有一个共同的 id,它必须是键,如果不是这样,那么另一个列表应该是空的。

我似乎很难找出能够这样做的 Linq 语句,我认为这是 GroupBy 或 GroupJoin 的工作,但无法弄清楚它应该是什么样子..

MVC:https://dotnetfiddle.net/BIbPqY

using System;
using System.Collections.Generic;

    
public class Program

    public static void Main()
    
        Dictionary<string, object> openWith =
                new Dictionary<string, object>();
        openWith.Add("txt", "notepad.exe");
        openWith.Add("bmp", "paint.exe");
        openWith.Add("dib", "paint.exe");
        openWith.Add("rtf", "wordpad.exe");
        
        Registration reg1 = new Registration()
        
            id = 1,
            attributes = openWith
        ;
    
        Registration reg2 = new Registration()
        
            id = 2,
            attributes = openWith
        ;

        Registration reg3 = new Registration()
        
            id = 1,
            attributes = openWith
        ;
        
        Registration reg4 = new Registration()
        
            id = 2,
            attributes = openWith
        ;
        
        List<Registration> oldReg = new List<Registration>() reg1, reg2 ; 
        List<Registration> newReg = new List<Registration>() reg3, reg4 ;
        
        Console.WriteLine("Hellow World");
    
    
    public class Registration
    
        public int id get; set;
        public Dictionary<string, object> attributes get; set;
    

我目前的处理方式是使用 groupBy 创建两个字典

Dictionary<int, List<Registration>> oldRegDic = 
        oldReg.GroupBy(o => o.id).ToDictionary(g => g.Key, g => g.ToList());
Dictionary<int, List<Registration>> newRegDic = 
        newReg.GroupBy(o => o.id).ToDictionary(g => g.Key, g => g.ToList());

        Dictionary<int, (List<Registration>, List<Registration>)> oldAndNewRegistrationDictionary = new();

        foreach (KeyValuePair<int, List<Registration>> newReg in newRegistrationDictionary)
        
            (List<EntityRegistration>, List<EntityRegistration>) oldNewPair = new()
            
                Item1 = oldRegDic[newReg.Key], Item2 = newRegDic[newReg.Key]
            ;
        

然后遍历它们并将它们添加到新字典中,但这看起来效率很低。

【问题讨论】:

Dictionary&lt;int, List&lt;Registration&gt;, List&lt;Registration&gt;&gt; 没有意义。 Dictionary&lt;TKey, TValue&gt; 只接受两个泛型类型参数。也许您打算拥有一个包含两个列表的类? class Foo public List&lt;Registration&gt; list1, list2; 然后有Dictionary &lt;int, Foo&gt; ? 这是为了避免为它制作一个完整的课程,但我明白你的意思 【参考方案1】:

这里有 Full Join 很好,但是可以通过两个查询来模拟:

var query1 = 
    from n in newReg
    join o in oldReg on n.id equals o.id into gj
    from o in gj.DefaultIfEmpty()
    select new  id = n.id, n, o ;

var query2 = 
    from o in oldReg
    join n in newReg on o.id equals n.id into gj
    from n in gj.DefaultIfEmpty()
    where n == null
    select new  id = o.id, n, o ;

var result = query1.Concat(query2)
    .ToDictionary(x => x.id, x => Tuple.Create(x.o, x.n));

【讨论】:

以上是关于如何将两个列表解析为字典,其中的 id 属性都成为键?的主要内容,如果未能解决你的问题,请参考以下文章

Python列表元素为字典时,如何根据其中某个相同的键值进行元素合并

如何将 JSON 字典列表转换为 Snowflake 中的字符串列表?

将 HTML 表解析为 Python 列表?

如何将 Typescript 类型定义为字符串字典但具有一个数字“id”属性

如何将返回的字典变成一个大列表?

如何将字典列表转换为 JSON