通过分组列表进行诅咒以构建分层数据集

时间:2018-03-20 17:53:09

标签: c# loops

我有两个班级。ItemItemSetItemSet可以是另一个ItemSet的父项或子项,并将其存储在名为sets的属性中,并且类型为List<ItemSet>。此外,ItemSet具有另一个属性,可以在其中保存类型Item的列表。 ItemSet上有一个方法Add(),它允许我们向其添加一个ItemSet或单个Items。

ItemSetClass

Public Class ItemSet
{
    Public List<ItemSet> Sets {get; set;}
    Public List<Item> Items {get; Set;}
}

这是我的问题所在。我有一些功能允许用户将数据分组到这些集合中,最终指定父集合和子集等的集合。这些集合基于数据库中的列并且有效值。

我有一个方法,它当前生成具有各自有效值的组的字典。 Dictionary<string,List<object>> GroupDictionary

这样字典中的值如下所示:

{Group1Name,[Group1Value1,Group1Value2,Group1Value3]},

{Group2Name,[Group2Value1,Group2Value2,Group2Value3]},

{Group3Name,[Group3Value1,Group3Value2,Group3Value3]},

我希望能够遍历此列表,以便我可以构建集合来表示适当的组。这样,集合的树表示看起来像......

Group1Value1
    Group2Value1
        Group3Value1
        Group3Value2
        Group3Value3
    Group2Value2
        Group3Value1
        Group3Value2
        Group3Value3
    Group2Value3
        Group3Value1
        Group3Value2
        Group3Value3
Group1Value2
    Group2Value1
        Group3Value1
        Group3Value2
        Group3Value3
    Group2Value2
        Group3Value1
        Group3Value2
        Group3Value3
    Group2Value3
        Group3Value1
        Group3Value2
        Group3Value3

这里的想法是这里的各个项目将保持在最低的组级别(在本例中为组3),并将根据其父组的特征进行过滤。

我似乎可以绕过正确的方法绕过这个问题,因为它需要多次遍历组字典来构建相关的层次结构。

这是我到目前为止所拥有的。

List<string> keyList = GroupDict.Keys.ToList<string>();
        var t = 0;
        ItemSet currentItemSet = new ItemSet();
        List<object> currentGroupValues = new List<object>();
        foreach (var key in keyList)
        {
            currentGroupValues = GroupDict[key];
            foreach (var value in currentGroupValues)
            {
                //Build new ItemSet
                ItemSet thisSet = new ItemSet();
                thisSet.DisplayText = value.ToString();
                currentWellSet.Add(thisSet);
                //if(lowest level) {currentWellSet.Add(items)}
                currentWellSet = thisSet;
            }
        }

1 个答案:

答案 0 :(得分:2)

当您从数据库获取分层数据时,它将如下所示:

enter image description here

然后,您将查询数据库并获取DataTable。我根据您在下面的代码中提供的数据构建了一个数据表,然后递归地将表中的数据放入您的递归结构中。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;


namespace ConsoleApplication31
{
    class Program
    {

        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Group", typeof(string));
            dt.Columns.Add("Parent", typeof(string));
            dt.Columns.Add("Child", typeof(string));

            dt.Rows.Add(new object[] { "Group1Name", null, "Group1Value1" });
            dt.Rows.Add(new object[] { "Group1Name", "Group1Value1", "Group2Value1" });
            dt.Rows.Add(new object[] { "Group1Name", "Group2Value1", "Group3Value1" });
            dt.Rows.Add(new object[] { "Group1Name", "Group2Value1", "Group3Value2" });
            dt.Rows.Add(new object[] { "Group1Name", "Group2Value1", "Group3Value3" });
            dt.Rows.Add(new object[] { "Group1Name", "Group1Value1", "Group2Value2" });
            dt.Rows.Add(new object[] { "Group1Name", "Group2Value2", "Group3Value1" });
            dt.Rows.Add(new object[] { "Group1Name", "Group2Value2", "Group3Value2" });
            dt.Rows.Add(new object[] { "Group1Name", "Group2Value2", "Group3Value3" });
            dt.Rows.Add(new object[] { "Group1Name", "Group1Value1", "Group2Value3" });
            dt.Rows.Add(new object[] { "Group1Name", "Group2Value3", "Group3Value1" });
            dt.Rows.Add(new object[] { "Group1Name", "Group2Value3", "Group3Value2" });
            dt.Rows.Add(new object[] { "Group1Name", "Group2Value3", "Group3Value3" });
            dt.Rows.Add(new object[] { "Group2Name", null, "Group1Value2" });
            dt.Rows.Add(new object[] { "Group2Name", "Group1Value2", "Group2Value1" });
            dt.Rows.Add(new object[] { "Group2Name", "Group2Value1", "Group3Value1" });
            dt.Rows.Add(new object[] { "Group2Name", "Group2Value1", "Group3Value2" });
            dt.Rows.Add(new object[] { "Group2Name", "Group2Value1", "Group3Value3" });
            dt.Rows.Add(new object[] { "Group2Name", "Group1Value2", "Group2Value2" });
            dt.Rows.Add(new object[] { "Group2Name", "Group2Value2", "Group3Value1" });
            dt.Rows.Add(new object[] { "Group2Name", "Group2Value2", "Group3Value2" });
            dt.Rows.Add(new object[] { "Group2Name", "Group2Value2", "Group3Value3" });
            dt.Rows.Add(new object[] { "Group2Name", "Group1Value2", "Group2Value3" });
            dt.Rows.Add(new object[] { "Group2Name", "Group2Value3", "Group3Value1" });
            dt.Rows.Add(new object[] { "Group2Name", "Group2Value3", "Group3Value2" });
            dt.Rows.Add(new object[] { "Group2Name", "Group2Value3", "Group3Value3" });

            new ItemSet(dt);
        }
    }
    public class ItemSet
    {
        public static Dictionary<string, ItemSet> GroupDictionary = new Dictionary<string, ItemSet>();

        public string name { get; set; }
        public List<ItemSet> sets { get; set; }
        public DataRow items { get; set; }


        public ItemSet() { }
        public ItemSet(DataTable dt)
        {
            var groups = dt.AsEnumerable()
                .GroupBy(x => x.Field<string>("Group")).ToList();

            foreach(var group in groups)
            {
                ItemSet root = new ItemSet();
                ItemSet.GroupDictionary.Add(group.Key, root);
                RecursiveAdd(root, group.ToList());
            }

        }
        public void RecursiveAdd(ItemSet parent, List<DataRow> rows)
        {
            foreach (DataRow row in rows.Where(x => x.Field<string>("Parent") == parent.name))
            {
                ItemSet newItemSet = new ItemSet();
                newItemSet.name = (string)row["Child"];
                newItemSet.items = row;
                if (parent.sets == null) parent.sets = new List<ItemSet>();
                parent.sets.Add(newItemSet);

                RecursiveAdd(newItemSet, rows);
            }
        }
    }
}