I have two Generic lists having objects of class :
class Subject
{
public string Code { get; set; }
public string Name { get; set; }
}
And another class as below :
class Student
{
public string RollNo { get; set; }
public string Name { get; set;
}
And a List of type having Roll No and Subject codes as KeyValuePair for student as below :
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));
What I need is another Dictionary of type
Dictionary<string, List<Subject>> StSbList =
new Dictionary<string, List<Subject>>();
where StSbList should have a list of subjects for given student using dictionary RoleList having all the subjects for a given Roll No. using LINQ in C# 4.0 , something like
StSbList(st1.RollNo, {sb1,sb2,sb3});
I tried and was able merge to similar collections but struck with different type of collections. Any suggestions on any other better approach.
As rightly pointed by Douglas and Martin, both the solutions are working fine but on my test data ToLookup works faster so used the same.
Solution 1
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);
Solution 2
var tSbList = RoleList.ToLookup(kvp => kvp.Key, kvp =>
(from sub in listSub
where sub.Code.Equals(kvp.Value)
select sub).First());
Your question isn’t really clear. If you’re asking for an example of how to populate your dictionary, here’s one:
More succinctly using nested collection initializers:
Update: As others have pointed out, your definition of
RoleListas a dictionary is probably erroneous, since it will not allow you to define multiple subjects for the same student. What you need is a data structure that supports the representation of a many-to-many relation; for example, aList<T>ofTuple<string,string>, whereItem1of each tuple contains theStudent.RollNo, whilstItem2contains theSubject.Code:To convert this into a dictionary, you could use first use the
GroupByoperator, followed byToDictionary:Update2: For completeness, this is how to construct the dictionary from your definition of
RoleList(although this probably isn’t what you want):Update3: Adapted to work with the latest version of your code: