【问题标题】:Implementing recursive aggregation实现递归聚合
【发布时间】:2014-03-23 01:58:15
【问题描述】:

我正在创建一个需要在其中一个类中使用递归聚合的应用程序。手头的类被称为“组件”,并且组件可以由存储在列表中的子组件组成。以下代码显示了这一点。

    public class Component {
//vars for class
public String componentName;
public String componentShape;
public String componentColour;
public String componentMaterial;
public int numChildComps;

//list to store child components of component
public List<Component> childComponents;

public Component(string _componentName, string _componentShape, string _componentColour, string _componentMaterial, int _numChildComps)
{
    componentName = _componentName;
    componentShape = _componentShape;
    componentColour = _componentColour;
    componentMaterial = _componentMaterial;
    numChildComps = _numChildComps;

    //if component has no child components set list to null
    if (numChildComps == 0)
    {
        //instatiate new list
        childComponents = new List<Component>();
        childComponents = null;
    }
    else if(numChildComps != 0)//if not null then create child components for the amount stated above.
    {
        childComponents = new List<Component>();
        for (int i = 0; i < numChildComps; i++)
        {
            Console.WriteLine("Add details for child component " + (i+1));
            Console.WriteLine("Enter component Name: ");
            string name = Console.ReadLine();
            Console.WriteLine("Enter shape: ");
            string shape = Console.ReadLine();
            Console.WriteLine("Enter Colour: ");
            string colour = Console.ReadLine();
            Console.WriteLine("Enter Material: ");
            string material = Console.ReadLine();
            Console.WriteLine("Enter num child components: ");
            string num = Console.ReadLine();
            childComponents.Add(new Component(name, shape, colour, material, Int16.Parse(num)));//instatiate new child component with params and add to the list.
        }
    }
}

这将创建一个类,如果子组件数量的参数大于 0,则它将创建对象并将其存储在列表“childComponents”中。这工作正常。我的问题是我将如何检索列表中的项目。以以下为例,我有一个模型,它由一个组件组成,但该组件有 2 个组件,其中一个有另外 2 个,其中一个有一个组件:

Model
 -component
  -childComponent
    -childComponent
    -childComponent
      -childComponent
  -childComponent

显然,这可能会永远持续下去,我尝试创建一段代码来淘汰所有组件和子组件,但它不起作用,因为您需要知道模型拥有的组件总数,然后知道组件子组件和以此类推。

我尝试过的代码(没有模拟上面的例子)

    IEnumerable<SEModel> modelres = from SEModel sm in database
                                    select sm;
    foreach (SEModel item in modelres)
    {
      Console.WriteLine(item.getSetModelName);
      Console.WriteLine(item.componentList.First().componentName);
      foreach (SEComponent citem in item.componentList)
      {
       Console.WriteLine(citem.childComponents.First().componentName);
        foreach (SEComponent scitem in citem.childComponents)
        {
          Console.WriteLine(scitem.componentName);
        }
     }

如上所述,您必须知道带有子组件的组件数量,然后是它们的子组件等等。

【问题讨论】:

  • 请使用不起作用的递归显示您的代码。
  • 如果您知道组件的总数及其下方的所有子组件及其子组件等等,那么它就可以工作。这并不理想,因为每个模型的模型具有的组件数量会有所不同。

标签: c# aggregation


【解决方案1】:
public IEnumerable<Component> GetComponents()
{
    yield return this;

    foreach( var childComp in childComponents )
    {
        foreach( var comp in childComp.GetComponents() )
        {
            yield return comp;
        }
    }
}

如果您不确定yield return 是什么意思,read this

【讨论】:

  • 考虑到 OP 与递归的斗争,我认为 yield return 不合适。 :) 但是您的代码确实是最干净的解决方案。
  • 嘿,它是递归的! ;)
  • +1 很好的解决方案,只是总结一下yield return object是什么和做什么,它是实现枚举器时迭代器方法中使用的上下文关键字。基本上,它有两个用例:yield return obj; 返回序列中的下一项。 yield break; 停止返回序列元素(如果控制到达迭代器方法体的末尾,这会自动发生)。
  • 在环顾四周并阅读了这篇文章后,它就像一个魅力一样,感谢您的输入,也感谢其他所有人。
【解决方案2】:

如果您需要以平面列表的形式检索组件,您可以这样做:

public List<Component> GetAllComponents(List<Component> components)
{
   var result = new List<Component>();
   result.AddRange(components);

   foreach (var component in  components)
        result.AddRange(GetAllComponents(component.childComponents));

   return result;
}

var allComponents = GetAllComponents(Model.Components);

虽然我从你的问题中不确定你到底想做什么。

【讨论】:

    猜你喜欢
    • 2021-08-25
    • 2014-03-01
    • 2014-04-09
    • 2014-04-18
    • 1970-01-01
    • 1970-01-01
    • 2019-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多