如何处理值的值的值

本文关键字:处理 何处理 | 更新日期: 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.SetCsAdvFacestepObj.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
    }
}