我正在阅读包含3D元素数据的文本文件,并将它们存储在C#中的字典dict
中。主要对象是OPEN_SHELL
和CLOSED_SHELL
s。这些包含多个ADVANCED_FACE
个。这些又包含一个FACE_OUTER_BOUND
和多个FACE_BOUND
。它们再次包含更多值,依此类推,直到最终有数值。
现在我有一个包含
的班级Step
List<List>string>> closedShell; //contains all closed shells with their values
List<List<string>> openShell; //contains all open shells with their values
List<List<string>> closedShellAdvFace; //contains all closed advanced faces...
List<List<string>> openShellAdvFace; //contains all open advanced faces...
...
我遍历每个列表以获取下一个值,依此类推。现在这看起来并不高效,因为我使用重复代码来封闭和打开列表。 一个示例代码:
string closedShellKey = "";
string closedShellValue = "";
string openShellKey = "";
string openShellValue = "";
// For CLOSED_SHELLs
for (int shellListIndex = 0; shellListIndex < stepObj.GetClosedShells().Count; shellListIndex++)
{
for (int valuesCount = 1; valuesCount < stepObj.GetClosedShells()[shellListIndex].Count - 1; valuesCount++)
{
if (dict.ContainsKey(stepObj.GetClosedShells()[shellListIndex][valuesCount]))
{
closedShellKey = stepObj.GetClosedShells()[shellListIndex][valuesCount];
dict.TryGetValue(closedShellKey, out closedShellValue);
stepObj.SetCsAdvFace(SplitValues(closedShellValue));
} else
{
//Throw Exception
}
}
}
// For OPEN_SHELLs
for (int shellListIndex = 0; shellListIndex < stepObj.GetOpenShells().Count; shellListIndex++)
{
for (int valuesCount = 1; valuesCount < stepObj.GetOpenShells()[shellListIndex].Count - 1; valuesCount++)
{
if (dict.ContainsKey(stepObj.GetOpenShells()[shellListIndex][valuesCount]))
{
openShellKey = stepObj.GetOpenShells()[shellListIndex][valuesCount];
dict.TryGetValue(openShellKey, out openShellValue);
stepObj.SetOsAdvFace(SplitValues(openShellValue));
} else
{
//Throw Exception
}
}
}
这会继续下一个值等。
实施这些步骤的真正有效方法是什么?
也许创建一个openShellObject
和一个closedShellObject
进一步分开?
我如何处理包含不同数据的数据,这些数据又包含更多不同的数据等?
希望这很清楚
答案 0 :(得分:0)
首先摆脱两个for
循环,改为使用IEnumerable
:
var allShellKeys = stepObj.GetClosedShells().Union(stepObj.GetOpenShells()).SelectMany(i => i.Skip(1).Take(i.Count() - 2))
然后你可以在一个循环中迭代所有值:
string anyShellValue;
foreach (var anyShellKey in allShellKeys)
{
if (dict.TryGetValue(anyShellKey, out anyShellValue))
{
stepObj.SetCsAdvFace(SplitValues(anyShellValue));
}
else
{
//Throw Exception
}
}
答案 1 :(得分:0)
首先,请注意Dictionary.TryGetValue
已完成Dictionary.ContainsKey
的工作,因此您只需要前者。
如果我理解这一点,你需要迭代多个集合,根据每个集合类别应用仅在一步中变化的操作,例如:闭面,开面等。如何将该步骤与迭代代码分开?我建议使用模板方法模式或方法参数(MAP)。对于这个问题,我可能选择MAP,因为收集项目因类别而不是数据类型而异,可能意味着编码较少。
在下面的伪代码中,我假设每次迭代的最后一步总是涉及stepObj.SetCsAdvFace
之类的方法,它采用string[]
返回的SplitValues
值。这就是为什么在下面的Apply方法中,参数method
是一个带有string[]
参数的委托,因此它匹配stepObj.SetCsAdvFace
或stepObj.SetOsAdvFace
,无论哪个都需要相关集合。
private void Apply(List<List<string>> list, Action<string[]> method)
{
foreach (var items in list)
{
for (int valuesIndex = 1; valuesIndex < items.Count - 1; valuesIndex++)
{
var key = items[valuesIndex];
string values;
if (dict.TryGetValue(key, out values))
{
method(SplitValues(values));
}
else
{
//Throw Exception
}
}
}
}
Apply(stepObj.GetClosedShells(), stepObj.SetCsAdvFace);
Apply(stepObj.GetOpenShells(), stepObj.SetOsAdvFace);
...