c# - 合并两个列表和一个字典以创建一个字典

标签 c# .net linq c#-4.0

我有两个具有类对象的通用列表:

class Subject
 {
   public string Code { get; set; }
   public string Name { get; set; }
 }

另一个类如下:

class Student
{
    public string RollNo { get; set; }
    public string Name { get; set; 
}

以及具有卷号和主题代码的类型列表作为学生的 KeyValuePair,如下所示:

List<KeyValuePair<string,string>>  RoleList=
           new  List<KeyValuePair<string,string>> ();

Student st1=new Student();          
Subject sb1=new Subject();
Subject sb2=new Subject();
Subject sb3=new Subject();

RoleList.Add(new KeyValuePair<string,string>(st1.RollNo,sb1.Code));
RoleList.Add(new KeyValuePair<string,string>(st1.RollNo,sb2.Code));
RoleList.Add(new KeyValuePair<string,string>(st1.RollNo,sb3.Code));

我需要的是另一个Dictionary类型

Dictionary<string, List<Subject>> StSbList =
    new Dictionary<string, List<Subject>>();

其中 StSbList 应该有给定学生的科目列表,使用字典 RoleList 具有给定卷号的所有科目,使用 C# 4.0 中的 LINQ,类似于

 StSbList(st1.RollNo, {sb1,sb2,sb3});

我尝试并能够合并到类似的集合,但遇到了不同类型的集合。关于任何其他更好方法的任何建议。

正如 Douglas 和 Martin 正确指出的那样,这两种解决方案都工作正常,但在我的测试数据上 ToLookup 工作得更快,所以使用相同的解决方案。

解决方案一

Dictionary<string, List<Subject>> stSbList =
RoleList.GroupBy(kvp => kvp.Key)
        .ToDictionary(
            grouping => grouping.Key,
            grouping => grouping.Select(kvp => (from sub in listSub
                                                where sub.Code.Equals(kvp.Value)
                                                select sub).First()).ToList(),
            EqualityComparer<string>.Default);

方案二

var tSbList = RoleList.ToLookup(kvp => kvp.Key, kvp => 
             (from sub in listSub
              where sub.Code.Equals(kvp.Value)
              select sub).First());

最佳答案

你的问题不是很清楚。如果您要找一个如何填充字典的示例,这里有一个:

Dictionary<string, List<Subject>> stSbList = new Dictionary<string, List<Subject>>();
stSbList.Add(st1.RollNo, new List<Subject> { sb1, sb2, sb3 });
stSbList.Add(st2.RollNo, new List<Subject> { sb1, sb3 });
stSbList.Add(st3.RollNo, new List<Subject> { sb1, sb2 });

更简洁地使用嵌套集合初始化器:

Dictionary<string, List<Subject>> stSbList = new Dictionary<string, List<Subject>>
{
    { st1.RollNo, new List<Subject> { sb1, sb2, sb3 } },
    { st2.RollNo, new List<Subject> { sb1, sb3 } },
    { st3.RollNo, new List<Subject> { sb1, sb2 } },
};

更新:正如其他人所指出的,您对 RoleList 的定义因为字典可能是错误的,因为它不允许你为同一个学生定义多个科目。你需要的是一个支持多对多关系表示的数据结构;例如 List<T>Tuple<string,string> , 其中Item1每个元组的包含 Student.RollNo , 而 Item2包含 Subject.Code :

var roleList = new List<Tuple<string, string>>();
roleList.Add(Tuple.Create(st1.RollNo, sb1.Code));
roleList.Add(Tuple.Create(st1.RollNo, sb2.Code));
roleList.Add(Tuple.Create(st1.RollNo, sb3.Code));
roleList.Add(Tuple.Create(st2.RollNo, sb1.Code));
roleList.Add(Tuple.Create(st2.RollNo, sb3.Code));
roleList.Add(Tuple.Create(st3.RollNo, sb1.Code));
roleList.Add(Tuple.Create(st3.RollNo, sb2.Code));

要将其转换为字典,您可以先使用 GroupBy运算符,后跟 ToDictionary :

var subjects = new[] { sb1, sb2, sb3 }.ToDictionary(sb => sb.Code);

Dictionary<string, List<Subject>> stSbList =
    roleList.GroupBy(tuple => tuple.Item1)
            .ToDictionary(
                grouping => grouping.Key,
                grouping => grouping.Select(tuple => subjects[tuple.Item2]).ToList(),
                EqualityComparer<string>.Default);

更新2:为了完整起见,这是根据您对 RoleList 的定义构建字典的方法。 (虽然这可能不是你想要的):

var roleList = new Dictionary<string, string>();
roleList.Add(st1.RollNo, sb1.Code);
roleList.Add(st2.RollNo, sb2.Code);
roleList.Add(st3.RollNo, sb2.Code);

var subjects = new[] { sb1, sb2, sb3 }.ToDictionary(sb => sb.Code);

Dictionary<string, List<Subject>> stSbList = roleList.ToDictionary(
    kvp => kvp.Key,
    kvp => new List<Subject> { subjects[kvp.Value] });

更新3:适用于最新版本的代码:

var subjects = new[] { sb1, sb2, sb3 }.ToDictionary(sb => sb.Code);

Dictionary<string, List<Subject>> stSbList =
    RoleList.GroupBy(kvp => kvp.Key)
            .ToDictionary(
                grouping => grouping.Key,
                grouping => grouping.Select(kvp => subjects[kvp.Value]).ToList());

关于c# - 合并两个列表和一个字典以创建一个字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9342126/

相关文章:

C# WMI、性能计数器和 SNMP 天啊!

c# - 是否可以订阅覆盖的基本事件?

c# - 多线程文件写入

visual-studio-2010 - 需要在 Visual Studio 2010 中调试 LINQ 简单查询

c# - 已解析上下文 (.toList()) 和未解析上下文的区别

c# - 使用 Linq,如何按名称将列表分隔为分组对象?

c# - 带有本地引用的 Lambda/Action

c# - 如果工作簿包含数据透视表,则在添加数据后无法保存 Excel 工作表

c# - 在列表框中使用 SelectionChanged 取消选择项目时遇到问题

c# - WebAPI [授权] 属性。这里发生了什么?