我有一个爬虫程序,它按目录汇总文件类型。
类似的东西:
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个子目录(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
答案 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(我之前使用过它,它是一个救星)