列表<myobject>包含</myobject>

时间:2013-04-30 03:14:39

标签: c# linq

检查列表中是否存在一个条目的最快方式(编码方式)是什么? 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 个答案:

答案 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)

您可能希望将性能与以下代码的方法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;
    }
}