linq查询常见关联

时间:2012-04-22 06:08:04

标签: c# linq

我有一个我试图解决的linq问题,我有一些用户可以成为多个组的一部分,现在我能够返回哪些用户属于一个组,如下所示:

    List<Student> students = new List<Student>();
    public List<Student> ReturnStudentByGroupName(string groupName)
    {
        List<Student> student = (from g in students
                              where
                                  (from t in g.StudentGroup where t.GroupName == groupName select t).Count() > 0
                              select g).ToList();
        return student;
    }

我现在的问题是我需要找到多个群组的普通用户吗?例如,谁是A组和B组的共同成员。我不是在寻找这两个组的用户列表,它应该只返回用户如果他们属于这两个组。

有没有人知道如何使用两个字符串作为输入,即字符串firstgroupName,字符串secondgroupName。那么回归普通学生?

3 个答案:

答案 0 :(得分:2)

IEnumerable<Student> StudentsOfGroup(Group g)
{
    return students.Where(s => s.StudentGroup.Contains(g));
}

IEnumerable<Student> CommonStudents(IEnumerable<Group> groups)
{
    return groups
        .Select(StudentsOfGroup)
        .Aggregate((acc, g) => acc.Intersect(g));
}

或根据群组的数量,以下内容可能更快:

IEnumberable<Student> CommonStudents(IEnumerable<Group> groups)
{
    var groupSet = new HashSet<Group>(groups);
    return students.Where(s => groupSet.IsSubsetOf(s.StudentGroup));
}

答案 1 :(得分:2)

IEnumberable<Student> GroupIntersection(IEnumerable<Group> groups)
{
    return students
        .Where(s => groups.All(g => s.StudentGroup.Contains(g)));
}

答案 2 :(得分:1)

嗯,你说你只想返回属于A组和B组的用户列表,所以很自然你只需要用两个条件而不是一个来修改where语句。

    List<Student> students = new List<Student>();
    public List<Student> GetIntersectingStudents(string groupOne, string groupTwo)
    {
        var student = from s in students
                      let grps = s.StudentGroup.ConvertAll(gn => gn.GroupName)
                      where grps.Contains(groupOne) && grps.Contains(groupTwo)
                      select s;
        return student.ToList();
    }
    public List<Student> GetIntersectingStudents(params string[] groups)
    {
        var student = from s in students
                      let grps = s.StudentGroup.ConvertAll(gn => gn.GroupName)
                      where !groups.Except(grps).Any()
                      select s;
        return student.ToList();
    }

以下是一些方法,其中一个方法在方法中采用两个参数(你要求的是什么),另一个采用组列表(如果你需要从三个而不是两个,等等)< / p>

修改

我以为我会在这里抛出这个额外的方法,只是为了好玩。它汇编了所有组及其成员的列表。

    public static Dictionary<string, List<Student>> GetStudentGroups()
    {
        var temp = from s in students
                   let grps = s.StudentGroup.ConvertAll(gn => gn.GroupName)
                   from grp in grps
                   group s by grp
                   into g
                   select g;
        return temp.ToDictionary(grping => grping.Key, studnt => studnt.ToList());
    }