【问题标题】:Can I use LINQ to check if objects in a list have a unique ID?我可以使用 LINQ 检查列表中的对象是否具有唯一 ID?
【发布时间】:2016-02-19 15:11:18
【问题描述】:

假设我有一个包含像这样的对象的列表:

public class Person
{
    private string _name; 
    private string _id;
    private int _age;

    public Person 
    {
    }

    // Accessors
}

public class ManipulatePerson
{
    Person person = new Person();
    List<Person> personList = new List<Person>;

    // Assign values

    private void PopulateList();
    {
        // Loop 
        personList.Add(person);

        // Check if every Person has a unique ID
    }
}

我想检查每个人是否有一个唯一的 ID。我想根据 ID 是否唯一返回布尔值 true/false。这是我可以用 LINQ 实现的吗?

【问题讨论】:

标签: c# linq list object


【解决方案1】:

请注意,您甚至可以直接利用 HashSet&lt;&gt;

var hs = new HashSet<string>();
bool areAllPeopleUnique = personList.All(x => hs.Add(x.Id));

(也是我平时使用的代码)

它的优点是在最好的情况下(存在一些重复)它会在分析所有 personList 集合之前停止。

【讨论】:

  • 请交叉路口! :D
  • 这很好,但更好的是覆盖哈希码,然后你可以直接这样做 var hs = new HashSet();
  • @user853710 或者您可以使用特殊的GetHashCode 创建一个单独的IEqualityComparer&lt;&gt;
  • true,两者都是有效的。
  • 嘿,我想知道你是否可以回答另一个问题,继续原来的答案?
【解决方案2】:

我会使用 Distinct 然后检查计数,例如:

bool bAreAllPeopleUnique = (personList.Distinct(p => p.ID).Count == personList.Count);

但是正如@Ian 所说,您需要将property 添加到Person 类中,以便您可以像这样访问ID:

public string ID
{
    get { return _id; }
}

实现这一点的“更好”方法是添加如下方法:

private bool AreAllPeopleUnique(IEnumerable<Person> people)
{
    return (personList.Distinct(p => p.ID).Count == personList.Count);
}

注意:该方法采用IEnumerable 而非列表,因此任何实现该接口的类都可以使用该方法。

【讨论】:

    【解决方案3】:

    最好的方法之一是覆盖EqualsGetHashCode,并实现IEquatable&lt;T&gt;

    public class Person : IEquatable<Person>
    {
         public string Id { get; set; }
    
         public override bool Equals(object some) => Equals(some as Person);
         public override bool GetHashCode() => Id != null ? Id.GetHashCode() : 0;
         public bool Equals(Person person) => person != null && person.UniqueId == UniqueId;
    }
    

    现在您可以使用HashSet&lt;T&gt; 来存储独特的对象,而且您不可能存储重复的对象。此外,如果您尝试添加重复项,Add 将返回 false

    注意:我的 IEquatable&lt;T&gt;Equals/GetHashCode 覆盖是非常基本的,但这个示例实现应该给你一个很好的提示,告诉你如何优雅地处理你的场景。

    您可以查看此问答以了解如何实施 GetHashCode What is the best algorithm for an overridden System.Object.GetHashCode?

    也许这个其他问答对你来说可能很有趣:Why is it important to override GetHashCode when Equals method is overridden?

    【讨论】:

      【解决方案4】:

      您可以使用GroupBy 获取独特的物品:

      var result = personList.GroupBy(p=> p.Id)
                         .Select(grp => grp.First())
                         .ToList();
      

      【讨论】:

      • 可以使用聚合Key。在 10 万条记录上,这是一个显着的改进 Select(grp => grp.Key)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      • 2018-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-13
      相关资源
      最近更新 更多