在List <object> </object>中查找对象的更有效方法

时间:2013-02-21 08:33:45

标签: c# .net list

假设已arrRowLength&amp; arrColLength已正确定义并已分配,MyObjectList<MyObject>已实例化并填充了少量对象。

class MyObject
{
    public MyObject() { }
    public int rowIndex {get; set;}
    public int colIndex {get; set;}
} 

List<MyObject> MyObjectList = new List<MyObject>();

for (int r = 1; r <= arrRowLength; r++)
{
    for (int c = 1; c <= arrColLength; c++)
    {
         MyObject mo = MyObjectList.Find(item => (item.rowIndex == r && item.colIndex == c));
         if(mo != null)
         {
              //found, do sth...
         }
    }
}

以上是我目前从MyObject找到MyObjectList对象的方法,其中rowIndexcolIndex等于rc in for循环。

但是,Find()具有 O(n)复杂度。 MyObjectList越大,所需的时间越长。所以我想知道是否有更好/更有效的方式来找到对象。如何使用.BinarySearch()方法实现此功能?

有什么建议吗?感谢。

4 个答案:

答案 0 :(得分:8)

这取决于您的实际需求,但选择更合适的数据结构可能是一种方法。

一个示例是以Tuple<int, int>为键的字典,其中第一项是行索引,第二项是列索引。 “搜索”现在将是查找和O(1):

Dictionary<Tuple<int, int>, MyObject> MyObjects;
MyObject o;
if(MyObjects.TryGetValue(Tuple.Create(r, s), out o)
{
    //found, do sth...
}

向字典添加新对象如下所示:

MyObjects.Add(Tuple.Create(o.rowIndex, o.colIndex), o);

如果 - 由于某种原因 - 您需要在另一个方法中迭代所有对象,您仍然可以使用字典的Values属性来执行此操作:

foreach(var o in MyObjects.Values)
{
    // do something for each of your objects.
}

答案 1 :(得分:1)

您可以使用SortedList<>及其方法IndexOfKey(),它使用二进制搜索。

如果在SortedList object; otherwise, -1.

中找到密钥,则返回密钥参数的从零开始的索引

查看http://msdn.microsoft.com/en-us/library/system.collections.sortedlist(v=vs.100).aspx

答案 2 :(得分:1)

减少迭代次数的另一种方法:

  1. 排序MyObjectList:by rowIndex Asc - &gt; by colIndex Asc
  2. 使用MyObjectList循环对foreach进行迭代,直到rowIndex等于arrRowLength
  3. 这种方法消除了迭代的必要性2d-matrix +减少List<MyObject>中访问过的实例的数量

答案 3 :(得分:0)

另一个想法 - 对于只需要查找特定行(或列)而不是单元格的情况,可以使用Lookup类:

Lookup<int, MyObject> rowIndex = MyObjectList.ToLookup(o => o.rowIndex, o => o);

通过简单引用,您可以快速检索给定行i的所有单元格:

IEnumerable<MyObject> rowCells = rowIndex[i];