我有一个清单
List<MyObject> myList
我正在向列表添加项目,我想检查该对象是否已经在列表中。
所以在我这样做之前:
myList.Add(nextObject);
我想知道nextObject是否已经在列表中。
对象“MyObject”具有许多属性,但比较基于两个属性的匹配。
在我将“MyObject”添加到“MyObject”列表之前进行检查的最佳方法是什么
我想到的唯一解决方案是从列表更改为字典,它们使键成为属性的连接字符串(这看起来有点不雅)
使用list或LINQ或其他什么的其他清洁解决方案?
答案 0 :(得分:116)
这取决于具体情况的需要。例如,假设字典方法非常好:
如果上述情况不符合您的具体情况,请使用 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.Contains
或myList.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
实现;您可以在类本身中覆盖GetHashCode
和Equals
。
答案 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();
});