linq GroupBy列表<类>进入新列表<类>



我有一个名为Person 的类

class Person() {
 string Name;
 string SSN;
}

以及一个包含许多重复的Person类常见实例的列表。例如

   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());

感谢

最好的方法是实现相等(直接在Person中,或通过IEqualityComparer<Person>),然后执行Distinct。例如

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();

您的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)

编译,因为GroupBy有一个重载,它为键选择器取一个lambda,为结果选择器取另一个lambda。它基本上按Name对集合进行分组,但返回了一个字符串集合(提取SSN属性)

你想做的是创建一个匿名类型来表示你的复合密钥:

.GroupBy(x => new {x.Name, x.SSN})

相关内容

  • 没有找到相关文章

最新更新