检查列表中是否存在一个条目的最快方式(编码方式)是什么? MyObject有2个属性
public class Name
{
public string FirstName{ get; set; }
public string LastName { get; set; }
}
然后我有另一个这样的课:
public class Foo
{
private List<Name> Names : new List<Name>();
public List<Name> Names { get; set; }
public bool Contains(Name x)
{
if (x == null)
return false;
>>> Navigate || Equals || Linq.Contains
>>> What's the easiest way to do this?
}
}
答案 0 :(得分:5)
最快的列表是O(n)
查找速度和O(1)
插入速度:
Atleast One
Names.Any(n=> x.FirstName == n.FirstName && x.LastName == n.LastName)
正好一个:
Names.Count(n=> x.FirstName == n.FirstName && x.LastName == n.LastName) == 1
Any()更快,因为它在找到Name的第一个实例时会短路。 Count每次都会搜索列表以查找Name的所有实例。
相反,您可以使用集合(例如 HashSet ,字典等),其中查找操作为O(1)
。但是,集合不具有与列表相同的属性。请注意,Hashset<string>
其中名称存储为FirstName + (delimeter) + LastName
之类的内容比其他任何选项都快。
您还可以使用 SortedList ,其中查找速度为O(log(n))
。但是,在排序列表中插入元素为O(nlog(n))
,因为必须在每次插入后对列表进行排序。
答案 1 :(得分:1)
我会说linq。很容易 http://msdn.microsoft.com/en-us/library/system.linq.enumerable.any.aspx
Names.Any(n=> n==x)
答案 2 :(得分:1)
使用Linq
应该更容易阅读。
以下是使用Any
的示例。
public bool Contains(Name x)
{
if (x == null)
return false;
return this.Names.Any(item => item.FirstName == x.FirstName && item.LastName == x.LastName);
}
建议:如果list
中的项目应该是唯一的,那么您可以使用System.Collections.Generic.HashSet
并使用System.Linq.Enumerable.Contains
..
答案 3 :(得分:1)
您可能希望将性能与以下代码的方法Contains
和Any
进行比较:
partial class Foo {
class NameComparer: IComparer<Name> {
public int Compare(Name x, Name y) {
return
object.ReferenceEquals(x, y)
||y.LastName==x.LastName&&y.FirstName==x.FirstName?0:~0;
}
public static readonly NameComparer Default=new NameComparer();
}
public bool Any(Name x) {
return
Names.Any(
y => object.ReferenceEquals(x, y)
||y.LastName==x.LastName&&y.FirstName==x.FirstName);
}
public bool Contains(Name x) {
return Names.BinarySearch(x, NameComparer.Default)>~0;
}
}