从Dictionary对象列表中查找值

时间:2013-05-07 17:29:56

标签: c# linq

我有可能是一个非常大的Dictionary对象列表,我需要从键中找到一个特定的值。我当然可以做像

这样的事情
foreach(Dictionary<long, string> t in Foo)
{
    if (t.TryGetValue(key, out name))
        break;
}

这将很高兴地遍历Foo,直到找到密钥或foreach结束。

为了加快速度,我宁愿使用少量的LINQ。如果这是一个普通的列表,我会没事的,但由于这是一个Dictionary对象列表,我不太清楚它是如何完成的。

帮助或建议表示赞赏。

4 个答案:

答案 0 :(得分:6)

我认为你已经写了你想要做的最有效的版本。由于Linq不能很好地处理输出参数,因此需要稍长的时间。但是你会这样做:

var dict = Foo.FirstOrDefault(d => d.ContainsKey(key));
if (dict != null) { dict.TryGetValue(key, out name); }

答案 1 :(得分:3)

此代码会更短,但需要更长的时间:

var dictWithKey = Foo.First(d => d.ContainsKey(key));
name = dictWithKey[key];

但真正的问题是,为什么你要使用一个字典列表,特别是因为你说你想“加快速度”。这告诉我这可能是你的代码不止一次做的事,对吗?

更合适的方法可能是保留包含所有键/值对的单个字典,这样您就可以进行单个查找而不是遍历多个字典。

答案 2 :(得分:0)

那么,根据Foo中词典的数量,使用Parallel LINQ(PLINQ)可能会有一个优势:

string name = null;
Parallel.ForEach(foo, f =>
                      {
                          if (name != null)
                              return;

                          if (f.ContainsKey(key))
                              name = f[key];
                      });

该实现假定给定键映射到相同的值或者该键在所有字典中是唯一的。此外,假设该值不为空。

5,000,000个词典包含一个键和一个值,比原始实现速度快150毫秒。

基准测试(2.4GHz Intel Core i5,带有两个物理内核和两个虚拟内核):

  • PLINQ:89ms
  • 原始解决方案:250毫秒

但是,我想强调的是,PLINQ并不一定总是让事情变得更快。在某些情况下,你有使用并行foreach循环遍历几个元素的代码,在后台启动线程的实际成本实际上要比使用简单的for循环迭代要昂贵得多 - 所以,当有很多时候使用它迭代的元素:)

答案 3 :(得分:-1)

您将密钥设置为长型。

long key = 1;
Dictionary<long, string> name = foo.Where(d => d.ContainsKey(key)).First();