键匹配时添加2个词典的内容,否则合并

时间:2013-06-11 11:01:00

标签: .net dictionary coding-style

我有一个爬虫程序,它按目录汇总文件类型。

类似的东西:

Class Directory
    Property Name As String
    Property TypeBreakdown As Dictionary(Of String, Integer)
    Property Directories As ICollection(Of Directory)
End Class

我递归到目录并添加Directory作为appororiate。当我展开堆栈时,我想聚合子目录细分。例如

假设Source目录有一个.cpp文件和2个子目录(SubDirSubDir2),我想要这样的东西......

{
    "Name": "Source",
    "TypeBreakdown": {".cpp": 1, ".exe": 10, ".c": 110},
    "Directories": [
        {
            "Name": "SubDir",
            "TypeBreakdown": {".exe": 10, ".c": 10},
            "Directories": [],
        },
        {
            "Name": "SubDir2",
            "TypeBreakdown": {".c": 100},
            "Directories": [],
        }
    ]
}

我正在创建各种TypeBreakdown词典,但我不确定如何将这些词组合起来:

如果密钥存在于任何一个密钥中,而不是两个密钥中,则包括密钥和值。如果密钥同时存在,则包括密钥并对值求和。

如果没有非常笨拙的for循环来检查每个密钥,有没有办法做到这一点?

这需要在没有框架更新的Vista上运行,这意味着我的目标是3.0,因此无法访问LINQ

3 个答案:

答案 0 :(得分:1)

你应该能够使用分组。类似的东西:

var combinedTypeBreakDown = 
    firstTypeBreakDown.Concat(secondTypeBreakDown)
       .GroupBy(kvp => kvp.Key, kvp => kvp.Value)
       .ToDictionary(g => g.Key, g => g.Sum());

答案 1 :(得分:1)

没有Linq:

    public Dictionary<string, int> CombineDictionaries(params Dictionary<string, int>[] dictionariesToCombine)
    {
        Dictionary<string, int> result = new Dictionary<string, int>();
        foreach (Dictionary<string, int> dictionary in dictionariesToCombine)
        {
            foreach (var item in dictionary)
            {
                if (result.ContainsKey(item.Key))
                    result[item.Key] += item.Value;
                else
                    result.Add(item.Key, item.Value);
            }
        }
        return result;
    }

你用

来调用它
var combinedBreakDown = CombineDictionaries(firstTypeBreakDown, secondTypeBreakDown);

答案 2 :(得分:1)

对于具体案例,我认为最好将组合细分作为属性添加到Directory类中,如下所示:

public Dictionary<string, int> GetFullTypeBreakdown()
{
  //assumes the client will not write to the result :D
  if ((Directories == null) || (Directories.Count == 0))
    return TypeBreakdown;

  var result = TypeBreakdown
    .Concat(Directories.SelectMany(d => d.GetFullTypeBreakdown()))
    .GroupBy(item => item.Key, item => item.Value)
    .ToDictionary(g => g.Key, g=> g.Sum());
  result.Dump();

  return result;
}

这会递归树并计算合并细分。但是,这使用了大量的LINQ,所以你至少应该使用LinqBridge(我之前使用过它,它是一个救星)