在Dictionary上使用LINQ Where子句时,如何返回相同类型的字典?

时间:2009-05-22 09:21:13

标签: c# linq optimization

我目前正在使用以下代码来实现这一目标,但似乎应该有更好的建议......建议?在我看来应该有一种方法可以跳过foreach ...

Dictionary<string,string> getValidIds(Dictionary<string,string> SalesPersons,List<string> ids)
{
    Dictionary<string,string> o = new Dictionary<string,string>();
    var ie = SalesPersons.Where<KeyValuePair<string, string>>(t => ids.Contains(t.Key));
    foreach (var i in ie)
    {
        o.Add(i.Key, i.Value);
    }
    return o;
}

3 个答案:

答案 0 :(得分:10)

非常确定你可以在Where调用的结果上调用ToDictionary:

Dictionary<string, string> GetValidIds(Dictionary<string, string> salesPersons,
    IList<string> ids)
{
    return salesPersons
        .Where(p => ids.Contains(p.Key))
        .ToDictionary(p => p.Key, p => p.Value);
}

答案 1 :(得分:6)

有趣的是,如果你通过字典(长度为N)首先进行枚举并检查列表(长度为M)以便包含,那么就可以获得O(NM)性能。

您可以构建一个HashSet<>个ID,但这似乎是多余的,因为我们已经有一个(预先散列好的)字典。

我会首先迭代id;因为字典查找(通过键)是O(1),这给出了O(M)性能 - 但是,这可能意味着你不使用LINQ(因为TryGetValue不会喜欢LINQ(并且引入一个元组太辛苦了......)

    Dictionary<string, string> getValidIds(
            IDictionary<string, string> salesPersons,
            IEnumerable<string> ids) {
        var result = new Dictionary<string, string>();
        string value;
        foreach (string key in ids) {
            if (salesPersons.TryGetValue(key, out value)) {
                result.Add(key, value);
            }
        }
        return result;
    }

这并不过分关注我,这比LINQ版本更多;它消除了O(N)的复杂性......


编辑;以下可能工作(我还没有测试过),但我认为这是对LINQ的滥用,当然也不会扩展到PLINQ等......请谨慎使用!!我也相信foreach方法只需要更少的开销,所以会更快......反正:

    Dictionary<string, string> getValidIds(
        IDictionary<string, string> salesPersons,
        IEnumerable<string> ids)
    {
        string value = null;
        return  (from key in ids
                where salesPersons.TryGetValue(key, out value) // HACK: v. dodgy
                select new { key, value })
                .ToDictionary(x=>x.key, x=>x.value);
    }

答案 2 :(得分:6)

在列表中查找内容似乎很烦人。如果列表只包含几个元素,那么没什么大不了的。如果List包含数千个元素,那么您将需要进行O(1)查找。 HashSet可以提供此功能。

Dictionary<string, string> getValidIds(
  Dictionary<string, string> SalesPersons,
  List<string> ids
)
{
  HashSet<string> idsFast = new HashSet<string>(ids);
  Dictionary<string, string> result = SalesPersons
    .Where(kvp => idsFast.Contains(kvp.Key))
    .ToDictionary(kvp => kvp.Key, kvp => kvp.Value)
  return result;
}