【发布时间】:2013-07-09 17:32:36
【问题描述】:
我想从原始列表字典值 (List<Dictionary<String,Object>>) 中提取已处理的字典值列表 (List<Dictionary<String,Object>>)。
原始字典可能包含字符串/数值
例如:
Dictionary<String, Object> rawListDict = new Dictionary<String, Object>();
rawListDict.Add("Product","Apple");
rawListDict.Add("Region", "West");
rawListDict.Add("Profit", 90);
原始列表:
苹果西 90
苹果东 10 号
苹果西 80
已处理列表:
苹果西 170
苹果东 10 号
考虑一个包含具有相同产品和地区的字典的列表,我想要一个字典,当“产品”和“地区”相同时添加“利润”。 (即)具有相似项目的字典列表被分组为单个字典,没有任何重复
注意:原始列表可以超过 30K 条目。 :-(
我已经通过蛮力技术实现了一个逻辑,它消耗了大量的内存和时间。有没有办法以 LINQ 风格或任何其他方法来减少时间和内存?
编辑:我更喜欢字典,因为成员/键的数量仅在运行时才知道。
我已经实现的代码:
//Get fields which could be used for combining values
var nonMeasurableFields = report.datagrid_fields.
Where(field => field.dataType.Equals(ImFieldDatatype.STRING_VALUE) || field.dataType.Equals(ImFieldDatatype.DATE_VALUE)).
Select(field => field.name).ToList();
if (nonMeasurableFields != null && nonMeasurableFields.Count > 0)
{
#region Outer For Loop
for (int index = 0; index < processedData.Count; index++)
{
var baseDict = processedData.ElementAt(index);
Dictionary<String, Object> compareDict = null;
#region Recursive Loop
for (int recursiveIndex = index + 1; recursiveIndex < processedData.Count; recursiveIndex++)
{
compareDict = processedData.ElementAt(recursiveIndex);
int matchesCount = 0;
#region comparison logic
foreach (var key in nonMeasurableFields)
{
var baseDictValue = baseDict[key];
var compareDictValue = compareDict[key];
if (baseDictValue == null && compareDictValue == null)
{
matchesCount++;
}
else
{
if (baseDictValue != null && compareDictValue == null)
{
matchesCount = 0;
}
else if (baseDictValue == null && compareDictValue != null)
{
matchesCount = 0;
}
else if (baseDictValue != null && compareDictValue != null)
{
if (baseDictValue.Equals(compareDictValue))
{
matchesCount++;
}
else
{
matchesCount = 0;
}
}
}
}
#endregion
#region If Match -- Combine
if (matchesCount == nonMeasurableFields.Count)
{
#region combine logic
// Combine the two dictionary ..
processedData.Remove(baseDict);
processedData.Remove(compareDict);
// combine the base and compare dict
Dictionary<String, Object> combinedDict = new Dictionary<string, object>();
var keyNeededInDict = baseDict.Keys.ToList();
foreach (var key in keyNeededInDict.ToList())
{
if (nonMeasurableFields.Contains(key))
{
combinedDict.Add(key, baseDict[key]);
}
else
{
Object value = Convert.ToDouble(baseDict[key]) + Convert.ToDouble(compareDict[key]);
combinedDict.Add(key, value);
}
}
processedData.Add(combinedDict);
index = -1; // Resetting the looping index so that the merging works for all values
recursiveIndex = -1; // Ensuring all the values are considered at least once whenever
// a change is made to the list (i.e merging the dict)
break;
#endregion
}
else
{
// No matches
// continue to next
}
#endregion
}
#endregion
}
#endregion
}
注意: 我将知道哪些键(键的值)是字符串类型和数字类型。 提供的示例仅用于演示目的。键和值仅在运行时才知道。 如果字符串值相等,我应该合并两个字典。我将在合并时添加数值。
编辑 2: 列表中的所有字典都将具有相同的键 不会丢弃任何值。具有相同值的字典将被合并。
【问题讨论】:
-
不清楚您要达到的目标。请显示输入和预期输出。
-
你有什么理由使用字典而不是正确的对象吗?
-
我想要一个字典,为了确定,输出应该是一个字典还是一个列表? 我已经通过蛮力技术实现了一个逻辑,告诉我们你已经得到了什么。
-
@DanielHilgarth 我已经更新了问题并添加了示例。键仅在运行时才知道。我应该检查所有字符串值并组合数值
-
@AlexFilipovici 我想要通过添加具有相同字符串值的字典形成的具有唯一条目的字典列表
标签: c# dictionary