如何检查对象是否已存在于列表中

时间:2010-08-08 16:28:02

标签: c# linq list

我有一个清单

  List<MyObject> myList

我正在向列表添加项目,我想检查该对象是否已经在列表中。

所以在我这样做之前:

 myList.Add(nextObject);

我想知道nextObject是否已经在列表中。

对象“MyObject”具有许多属性,但比较基于两个属性的匹配。

在我将“MyObject”添加到“MyObject”列表之前进行检查的最佳方法是什么

我想到的唯一解决方案是从列表更改为字典,它们使键成为属性的连接字符串(这看起来有点不雅)

使用list或LINQ或其他什么的其他清洁解决方案?

9 个答案:

答案 0 :(得分:116)

这取决于具体情况的需要。例如,假设字典方法非常好:

  1. 列表相对稳定(没有很多插入/删除,字典没有优化)
  2. 列表非常大(否则字典的开销毫无意义)。
  3. 如果上述情况不符合您的具体情况,请使用 Any()

    Item wonderIfItsPresent = ...
    bool containsItem = myList.Any(item => item.UniqueProperty == wonderIfItsPresent.UniqueProperty);'
    

    这将列出列表,直到找到匹配项,或直到它到达结尾。

答案 1 :(得分:61)

只需使用Contains方法即可。请注意,它基于相等函数Equals

工作
bool alreadyExist = list.Contains(item);

答案 2 :(得分:45)

如果可以维护使用这两个属性,您可以:

bool alreadyExists = myList.Any(x=> x.Foo=="ooo" && x.Bar == "bat");

答案 3 :(得分:7)

在这种情况下,您确定需要一个列表吗?如果您使用多个项目填充列表,性能将受到myList.ContainsmyList.Any的影响;运行时间将是二次的。您可能需要考虑使用更好的数据结构。例如,

 public class MyClass
    {
        public string Property1 { get; set; }
        public string Property2 { get; set; }

    }

    public class MyClassComparer : EqualityComparer<MyClass>
    {
        public override bool Equals(MyClass x, MyClass y)
        {
            if(x == null || y == null)
               return x == y;

            return x.Property1 == y.Property1 && x.Property2 == y.Property2;
        }

        public override int GetHashCode(MyClass obj)
        {
            return obj == null ? 0 : (obj.Property1.GetHashCode() ^ obj.Property2.GetHashCode());
        }
    }

您可以通过以下方式使用HashSet:

  var set = new HashSet<MyClass>(new MyClassComparer());
  foreach(var myClass in ...)
     set.Add(myClass);

当然,如果MyClass的这种平等定义是“普遍的”,则无需编写IEqualityComparer实现;您可以在类本身中覆盖GetHashCodeEquals

答案 4 :(得分:4)

另一点要提到的是,您应该确保您的平等功能符合您的预期。您应该覆盖equals方法以设置对象的哪些属性必须匹配才能使两个实例相等。

然后你就可以了 mylist.contains(项目)

答案 5 :(得分:3)

编辑:我先说过:


词典解决方案的优点是什么。对我来说似乎非常优雅,因为你只需要在创建字典时设置比较器。


当然,当它也是价值时,使用某些东西是不优雅的。

因此我会使用HashSet。如果以后的操作需要索引,那么在添加完成后我会从中创建一个列表,否则,只需使用hashset。

答案 6 :(得分:3)

这是一个快速控制台应用程序,用于描述如何解决问题的概念。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication3
{
    public class myobj
    {
        private string a = string.Empty;
        private string b = string.Empty;

        public myobj(string a, string b)
        {
            this.a = a;
            this.b = b;
        }

        public string A
        {
            get
            {
                return a;
            }
        }

        public string B
        {
            get
            {
                return b;
            }
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            List<myobj> list = new List<myobj>();
            myobj[] objects = { new myobj("a", "b"), new myobj("c", "d"), new myobj("a", "b") };


            for (int i = 0; i < objects.Length; i++)
            {
                if (!list.Exists((delegate(myobj x) { return (string.Equals(x.A, objects[i].A) && string.Equals(x.B, objects[i].B)) ? true : false; })))
                {
                    list.Add(objects[i]);
                }
            }
        }
    }
}

享受!

答案 7 :(得分:0)

简单但有效

MyList.Remove(nextObject)
MyList.Add(nextObject)

 if (!MyList.Contains(nextObject))
    MyList.Add(nextObject);

答案 8 :(得分:0)

如果您使用EF核心添加

 .UseSerialColumn();

示例

modelBuilder.Entity<JobItem>(entity =>
        {
            entity.ToTable("jobs");

            entity.Property(e => e.Id)
                .HasColumnName("id")
                .UseSerialColumn();
});