将带条件的递归树映射到平面列表

时间:2018-12-24 09:22:21

标签: c#

我正在编写一个c#应用程序,并且有一个看起来像这样的递归树:

Item1
|-Container(min 0, max 1)
| |-Item2
| | |-Container(min 0, max 1)
| |   |-Item5
| |-Item3
| | |-Container(min 1, max 1)
| |   |-Item8
|-Container(min 1, max 1)
| |-Item4
| |-Item7
|-Container(min 1, max 1)
  |-Item6

我需要将其转换为以下列表:

Item1-Item6-Item4
Item1-Item6-Item4-Item2
Item1-Item6-Item4-Item2-Item5
Item1-Item6-Item4-Item3-Item8
Item1-Item6-Item7
Item1-Item6-Item7-Item2
Item1-Item6-Item7-Item2-Item5
Item1-Item6-Item7-Item3-Item8

满足以下条件:

  • 如果容器的最小值大于0,则应始终将其项添加到父项,例如item4item7item6
  • 如果不是,则应将其添加到诸如item2item3item5之类的基本项目中,
  • 同一容器的项目未归入同一集合

1 个答案:

答案 0 :(得分:0)

经过深思熟虑,我终于找到了这个解决方案:

我的结果结构将是项目列表,此方法将获取根项目和项目列表,以便我可以在容器中查询具有绑定ID的项目

public static List<List<Item>> Map(Item item, List<Item> items)
{
    var result = new List<List<Item>> { new List<Item> { item } };
    item.Containers.ForEach(container =>
    {
        if (container.Min < 1)
        {
            var visited = new List<int>();
            container.ItemIds.ForEach(id =>
            {
                var localItem = items.Find(i => i.Id == id);
                var localItemList = Map(localItem, items);
                localItemList.Add(new List<Item>());
                var excludedVisited = result.Where(l => !l.Any(i => visited.Contains(i.Id))).ToList();
                var remainingNodes = result.Where(l => l.Any(i => visited.Contains(i.Id))).ToList();
                result = Product(excludedVisited, localItemList).Union(remainingNodes).ToList();
                visited.Add(id);
            });
        }
        else
        {
            var visited = new List<int>();
            var localResult = new List<List<Item>>();
            container.ItemIds.ForEach(id =>
            {
                var localItem = items.Find(i => i.Id == id);
                var localItemList = Map(localItem, items);
                var excludedVisited = result.Where(l => !l.Any(i => visited.Contains(i.Id))).ToList();
                var remainingNodes = result.Where(l => l.Any(i => visited.Contains(i.Id))).ToList();
                localResult.AddRange(Product(excludedVisited, localItemList).Union(remainingNodes).ToList());
                visited.Add(id);
            });
            result = localResult;
        }
    });
    return result;
}

您可以找到其用法示例here