我有两个具有类对象的通用列表:
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/