1

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

就像是:

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

我递归到目录并添加一个Directory适当的。当我展开堆栈时,我想汇总子目录细分。例如。

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

{
    "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

4

3 回答 3

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(我以前用过它,它是一个救命稻草)

于 2013-06-11T12:05:39.660 回答
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);
于 2013-06-11T11:53:45.010 回答
1

您应该能够使用分组。就像是:

var combinedTypeBreakDown = 
    firstTypeBreakDown.Concat(secondTypeBreakDown)
       .GroupBy(kvp => kvp.Key, kvp => kvp.Value)
       .ToDictionary(g => g.Key, g => g.Sum());
于 2013-06-11T11:08:40.260 回答