【问题标题】:linq GroupBy List<Class> into new List<Class> [closed]linq GroupBy List<Class> 进入新 List<Class> [关闭]
【发布时间】:2014-04-14 16:22:54
【问题描述】:

我有一个名为 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());

谢谢

【问题讨论】:

  • 您能解释一下您的意图吗 - Linq 语句的语法在通用时仅采用 List 中的一个类对象?我已经读了好几遍了,还是不明白你要达到什么目的

标签: c# linq


【解决方案1】:

最好的方法是实现相等(直接在Person 中,或通过IEqualityComparer&lt;Person&gt;),然后执行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();

【讨论】:

    【解决方案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})
    

    【讨论】:

      猜你喜欢
      • 2011-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-29
      • 1970-01-01
      • 1970-01-01
      • 2014-05-26
      相关资源
      最近更新 更多