快速查找列表<;T>;

本文关键字:gt lt 列表 查找 | 更新日期: 2023-09-27 17:59:45

我有两个通用列表。假设它们是List< A >List< B >

A具有一个属性,该属性的类型为List< B >。此属性包含B类型的对象,这些对象由对象A的一些其他属性过滤。

因此:

class A{
  public int Something1;
  public int Something2;
  public List<B> Something3;
}
class B{
  public int Anything1;
  public int Anything2;
}

我想将所有对象B作为列表添加到对象A(到名为Something3的属性),比如说对象A.Something1 == B.Anything1

我的问题是:将List<B>项目添加到List<A>项目中最有效的方法是什么?请注意,这两个列表中可能都有数十万个对象。

(VS2010;C#;.Net4)

快速查找列表<;T>;

Anything1属性上的B进行分组,并放入字典中。然后你可以循环浏览A的,并有效地挑选出B的列表:

Dictionary<int, List<B>> beegroups = bees.GroupBy(b => b.Anything1).ToDictionary(g => g.Key, g => g.ToList());
foreach (A a in ayes) {
  List<B> group;
  if (beegroups.TryGetValue(a.Something1, out group)) {
    a.Something3 = group;
  }
}

如果有您提到的那么多数据,那么选择&插入操作的顺序如下。

来自C#中的通用词典:

  1. Dictionary<int,A>

    • 选择:O(1)(表示复杂性)
    • 加:O(1)[或O(n)]
    • 基于哈希表
  2. SortedDictionary<int,A>

    • 选择:O(log n)
    • 添加:O(日志n)
    • 基于二进制搜索树
  3. SortedList<int,A>

    • 选择:O(log n)[或O(n)]
    • 加:O(n)
    • 基于排序的集合(相当大的数组)

请注意,如果数据数量相对较少,则List<int, A>将是好的。(根据您的数据大小,上面的顺序会重新排列。)

同时,您需要考虑C#中Collection类型的容量Collection类型是可调整大小的,因此如果缺少大小,则会将Collection重新创建为比以前大,并再次插入元素。这一点告诉您,如果您已经知道集合的大小,则应该在集合构造函数中设置容量。

在将添加到a列表之前,如果它存在于B列表中,我会使用Map Check

这里有一种替代方法,它可以更有效地利用LINQ,而不仅仅是替换每个A中的列表。使用组联接并将每个组中的项目添加到相应的A中。

List<A> myAs = ...;
List<B> myBs = ...;
var pairs = from a in myAs
            join b in myBs on a.Something1 equals b.Anything1 into TheseBs
            select new { A = a, TheseBs };
foreach (var pair in pairs)
{
    pair.A.Something3.AddRange(pair.TheseBs);
}