我有一个名为Person的类
class Person() {
string Name;
string SSN;
}
以及包含许多重复的Person类的常见实例的List。例如
Person.Name = "John";
Person.SSN = "123456789";
Person.Name = "John";
Person.SSN = "123456789";
Person.Name = "John";
Person.SSN = "123456789";
Person.Name = "John";
Person.SSN = "123456789";
Person.Name = "John";
Person.SSN = "123456789";
我试图找出Linq语句的语法,以便在常见时将List中的一个类对象添加到新列表中。
List<Person> newPerson = new List<Person>();
newPerson.AddRange(person.GroupBy(x => x.Name, x => x.SSN).Select(grp => grp.ToList().First()).ToList());
由于
答案 0 :(得分:3)
执行此操作的最佳方法是实现平等(直接在Person
或通过IEqualityComparer<Person>
),然后执行Distinct
。 E.g。
class Person : IEquatable<Person> {
// these should be properties, e.g. public string Name { get; set; }
string Name;
string SSN;
public override int GetHashCode() {
// XOR is not the best generally, but can work for something like this
return Name.GetHashCode() ^ SSN.GetHashCode();
}
public override bool Equals(object other) {
return Equals(other as Person);
}
public bool Equals(Person other) {
return other != null && this.Name == other.Name && this.SSN == other.SSN;
}
}
var newPerson = person.Distinct().ToList();
答案 1 :(得分:2)
您的GroupBy
语法略有偏差,并且您不需要所有这些ToList
来电:
newPerson.AddRange(person.GroupBy(x => new {x.Name, x.SSN})
.Select(grp => grp.First()));
或只是
newPerson = person.GroupBy(x => new {x.Name, x.SSN})
.Select(grp => grp.First())
.ToList();
因为你无论如何都要从空列表开始。
详细说明
您的原始语法:
.GroupBy(x => x.Name, x => x.SSN)
编译因为有一个overload for GroupBy
,它为键选择器使用lambda,为结果选择器使用另一个lambda。它基本上按Name
对您的集合进行了分组,但返回了一组字符串(提取SSN
属性)
您要做的是创建一个代表复合键的匿名类型:
.GroupBy(x => new {x.Name, x.SSN})