如何处理值的值

时间:2014-11-11 09:15:17

标签: c# list object recursion

我正在阅读包含3D元素数据的文本文件,并将它们存储在C#中的字典dict中。主要对象是OPEN_SHELLCLOSED_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进一步分开? 我如何处理包含不同数据的数据,这些数据又包含更多不同的数据等?

希望这很清楚

2 个答案:

答案 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.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);
...