如何处理值的值的值
本文关键字:处理 何处理 | 更新日期: 2023-09-27 18:30:01
我正在读取一个文本文件,该文件包含3D元素的数据,并将它们存储在C#中的字典dict
中。主要对象是OPEN_SHELL
s和CLOSED_SHELL
s。它们包含多个ADVANCED_FACE
s。它们再次包含单个FACE_OUTER_BOUND
和多个FACE_BOUND
s。它们又包含更多的值,依此类推,直到最终出现数值。
现在我有一个包含的类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
来进一步分离?我将如何处理包含不同数据的数据,这些数据又包含其他不同的数据,等等。?
希望这是足够清楚的
首先,注意Dictionary.TryGetValue
已经完成了Dictionary.ContainsKey
的工作,所以您只需要前者。
如果我理解这一点,您需要对多个集合进行迭代,根据每个集合类别,例如封闭面、开放面等,应用仅在一个步骤中变化的操作。如何将该步骤与迭代代码分离?我建议要么模板方法模式,要么方法作为参数(MAP)。对于这个问题,我可能会选择MAP,因为收集项目因类别而非数据类型而异,这可能意味着编码更少。
在下面的伪代码中,我假设每次迭代的最后一步总是涉及像stepObj.SetCsAdvFace
这样的方法,该方法采用SplitValues
返回的string[]
值。这就是为什么在下面的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);
...
首先去掉两个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
}
}