在组中查找唯一值

时间:2017-06-06 12:47:25

标签: c# linq

猜猜我有两组

using System.Collections.Generic;

namespace ConsoleApplication
{
    internal class Student
    {
        public string Name;
        public string Surname;
        public int Mark;
    }

    internal class Program
    {
        private static void Main()
        {
            var twoGroups = new List<List<Student>>
            {
                new List<Student>
                {
                    new Student { Name = "Anna",  Surname = "Mors",  Mark = 4 }, 
                    new Student { Name = "Jimmy", Surname = "Lemon", Mark = 4 }
                },
                new List<Student>
                {
                    new Student { Name = "Anna",  Surname = "Mors",   Mark = 4 }, 
                    new Student { Name = "Tommy", Surname = "Wojski", Mark = 4 },
                    new Student { Name = "Jimmy", Surname = "Lemon",  Mark = 4 }
                }
            };
        }
    }
}

我如何通过linq从两个组(通过姓名或任何其他财产)获得独特的人?

显然有汤米,但我不知道如何用linq选择他(或选择一个独特的人名单。

UPD

另外,我可以选择只包含独特学生的小组。

using System.Collections.Generic;

namespace ConsoleApplication
{
    internal class GroupOfStudents
    {
        public string Code;
        public List<Student> Students;
    }

    internal class Student
    {
        public string Name;
        public string Surname;
        public int Mark;
    }

    internal class Program
    {
        private static void Main()
        {
            var twoGroups = new List<GroupOfStudents>
            {
                new GroupOfStudents
                {
                    Code = "A1",
                    Students = new List<Student>
                    {
                        new Student { Name = "Anna",  Surname = "Mors",  Mark = 4 }, 
                        new Student { Name = "Jimmy", Surname = "Lemon", Mark = 4 }
                    }
                },
                new GroupOfStudents()
                {
                    Code = "B2",
                    Students = new List<Student>
                    {
                        new Student { Name = "Anna",  Surname = "Mors",   Mark = 4 }, 
                        new Student { Name = "Tommy", Surname = "Wojski", Mark = 4 },
                        new Student { Name = "Jimmy", Surname = "Lemon",  Mark = 4 }
                    }
                }
            };
        }
    }
}

我想我需要选择学生并将他推到同名的新组,对吗?

2 个答案:

答案 0 :(得分:3)

  1. 将嵌套列表展开为一个SelectMany()
  2. 按唯一标准GroupBy()分组(我选择所有属性)
  3. 选择唯一记录Where()
  4. 代码:

    List<Student> result = twoGroups.SelectMany(x => x)
                           .GroupBy(x => new { x.Name, x.Surname, x.Mark })
                           .Where(x => x.Count() == 1)
                           .Select(x => x.First())
                           .ToList();
    

答案 1 :(得分:2)

您可以使用SelectManyGroupByCount

IEnumerable<Student> uniqueStudents = twoGroups 
    .SelectMany(list => list)
    .GroupBy(student => student.Name)
    .Where(g => g.Count() == 1)
    .Select(g => g.First());

这仅选择在两个(或两个)列表中的一个中未多次包含的学生。

如果要按多个属性分组,请使用匿名类型

    .GroupBy(student => new { student.Name, student.Surname })

如果您想在同一个列表中允许重复,但不允许在多个列表中重复:

IEnumerable<Student> uniqueStudents = twoGroups 
    .SelectMany((list, index) => list.Select(student => new { student, index }))
    .GroupBy(x => x.student.Name)
    .Where(g =>
    {
        int index = g.First().index;
        return g.Skip(1).All(x => x.index == index);
    })
    .Select(g => g.First().student);

度Acc。您的修改

如果您要从同样出现在其他组中的列表中删除所有学生:

var studentNameLookup = twoGroups.SelectMany(g => g.Students).ToLookup(s => s.Name);
twoGroups.ForEach(g => g.Students.RemoveAll(s => studentNameLookup[s.Name].Count() > 1));