2

检查列表中是否存在一个条目的最快方法(明智的编码)是什么?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?
   }
}
4

4 回答 4

5

List 最快的是O(n)查找速度和O(1)插入速度:

最后一个

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 的所有实例。

相反,您可以使用查找操作所在的集合(例如HashSetDictionaryO(1)等) 。但是,集合不具有与列表相同的属性。请注意,Hashset<string>将名称存储为类似FirstName + (delimeter) + LastName的位置比您拥有的任何其他选项都快。

您还可以使用查找速度为的SortedListO(log(n))。但是,在排序列表中插入元素是O(nlog(n))因为您必须在每次插入后保持列表排序。

于 2013-04-30T03:19:49.953 回答
1

您可能希望将性能与方法ContainsAny以下代码进行比较:

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;
    }
}
于 2013-04-30T04:53:04.003 回答
1

我会说 linq .Any 很简单 http://msdn.microsoft.com/en-us/library/system.linq.enumerable.any.aspx

Names.Any(n=> n==x)
于 2013-04-30T03:20:16.130 回答
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..

于 2013-04-30T03:21:10.813 回答