简体   繁体   English

复杂的循环c#-循环访问每一列以创建“配置”

[英]Complex for loop c# - Iterating each column row to create “Configurations”

I've been trying to think the best route to do a loop for this data. 我一直在尝试为该数据执行循环的最佳途径。 I have a table that can be seen below and need to iterate through all column configurations. 我有一个可以在下面看到的表,需要遍历所有列配置。 The column count is dynamic. 列数是动态的。 Results should be: 结果应为:

Apple-Broccoli-Ice Cream 苹果花椰菜冰淇淋
Apple-Broccoli-Pie 苹果花椰菜派
Apple-Carrots-Ice Cream 苹果胡萝卜冰激凌
Apple-Carrots-Pie 苹果胡萝卜派
Apple-Peas-Ice Cream 苹果豌豆冰激凌
Apple-Peas-Pie 苹果豌豆派
Apple-Green Beans-Ice Cream 苹果绿豆冰淇淋
Apple-Green Beans-Pie 苹果绿豆派
Orange-Broccoli-Ice Cream 橙色西兰花冰激凌
Orange-Broccoli-Pie 橙花椰菜派
Orange-Carrots-Ice Cream 橙胡萝卜冰激淋
Orange-Carrots-Pie 橙色胡萝卜派
Orange-Peas-Ice Cream 橙豆冰奶油
Orange-Peas-Pie 橙豌豆饼
Orange-Green Beans-Ice Cream 橙绿色豆类冰淇淋
Orange-Green Beans-Pie 橙绿豆饼

My "manual" code is below, but I would like it to be more dynamic regarding columns (there could be 2,3,5, etc.) 我的“手动”代码在下面,但我希望它在列方面更具动态性(可能有2、3、5等)

What is the best way to make a dynamic loop when the columns vary? 当列变化时进行动态循环的最佳方法是什么?

Note: I have an object "Configuration" and a list of those objects called "configs" 注意:我有一个对象“配置”和一个名为“ configs”的对象的列表

Image of Configuration Table 配置表图片

在此处输入图片说明

List<Configuration> configs = new List<Configuration>();

// iterate left to right
for (int i1 = 0; i1 < dataGridConfigTable.Rows.Count - 1; i1++)
{
    string param1 = dataGridConfigTable.Rows[i1].Cells[0].Value.ToString() ?? string.Empty;

    if (!string.IsNullOrEmpty(param1))
    {
        for (int i2 = 0; i2 < dataGridConfigTable.Rows.Count - 1; i2++)
        {
            string param2 = dataGridConfigTable.Rows[i2].Cells[1].Value.ToString() ?? string.Empty;

            if (!string.IsNullOrEmpty(param2))
            {
                for (int i3 = 0; i3 < dataGridConfigTable.Rows.Count - 1; i3++)
                {
                    string param3 = dataGridConfigTable.Rows[i3].Cells[2].Value.ToString() ?? string.Empty;

                    if (!string.IsNullOrEmpty(param3))
                    {
                        for (int i4 = 0; i4 < dataGridConfigTable.Rows.Count - 1; i4++)
                        {
                            string param4 = dataGridConfigTable.Rows[i4].Cells[3].Value.ToString() ?? string.Empty;

                            if (!string.IsNullOrEmpty(param4))
                            {
                                for (int i5 = 0; i5 < dataGridConfigTable.Rows.Count - 1; i5++)
                                {
                                    string param5 = dataGridConfigTable.Rows[i5].Cells[4].Value.ToString() ?? string.Empty;

                                    if (!string.IsNullOrEmpty(param5))
                                    {
                                        configs.Add(new Configuration(param1, param2, param3, param4, param5));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

You are looking for the Cartesian product to produce the final outputs. 您正在寻找笛卡尔积来产生最终输出。

So first convert the table (or data source you have) into a list of lists of string, then apply the cartesian product to every list in the collection. 因此,首先将表(或您拥有的数据源)转换为字符串列表列表,然后将笛卡尔乘积应用于集合中的每个列表。

    //this function produce the cartesian product of two lists
    List<string> CartesianProduct(List<string> lst1, List<string> lst2, string seperator)
    {
        var res = new List<string>();
        for (int i = 0; i < lst1.Count; i++)
        {
            for (int j = 0; j < lst2.Count; j++)
            {
                res.Add(lst1[i] + seperator + lst2[j]);
            }
        }
        return res;
    }

    //This function apply the cartesian product to all lists
    List<string> CartesianProduct(List<List<string>> lsts, string seperator)
    {
        List<string> res = lsts[0];

        for (int i = 1; i < lsts.Count; i++)
        {
            res = CartesianProduct(res, lsts[i], seperator);
        }
        return res;
    }

you might use this method to convert your table into lists 您可以使用此方法将表转换为列表

       var dt1 = new DataTable(); //your data source
        var lsts = new List<List<string>>();

        for (int i = 0; i < dt1.Columns.Count; i++)
        {
            var singleColumnLst = new List<string>();
            for (int j = 0; j < dt1.Rows.Count; j++)
            {
                singleColumnLst.Add((string)dt1.Rows[i][j]);
            }
            lsts.Add(singleColumnLst);
        }

        //final results
        var allItems = CartesianProduct(lsts, "-");

EDIT: OK, sorry, missed the dynamic thing. 编辑:好的,抱歉,错过了动态的东西。 Here you go. 干得好。 EDIT1: Not sure why one would down vote this example. EDIT1:不知道为什么这个例子会被否决。 Works fine for me. 对我来说很好。 Here us update the make the algo work with the datatable. 在这里,我们更新使算法与数据表一起使用。

static void Main(string[] args)
        {

            System.Data.DataTable dataGridConfigTable = new System.Data.DataTable();
            dataGridConfigTable.Columns.Add("Parameter1");
            dataGridConfigTable.Columns.Add("Parameter2");
            dataGridConfigTable.Columns.Add("Parameter3");

            var row = dataGridConfigTable.NewRow();
            row[0] = "Apple";
            row[1] = "Broccoli";
            row[2] = "Ice Cream";
            dataGridConfigTable.Rows.Add(row);
            row = dataGridConfigTable.NewRow();
            row[0] = "Orange";
            row[1] = "Carrots";
            row[2] = "Pie";
            dataGridConfigTable.Rows.Add(row);
            row = dataGridConfigTable.NewRow();
            row[1] = "Peas";
            dataGridConfigTable.Rows.Add(row);
            row = dataGridConfigTable.NewRow();
            row[1] = "Grean Beans";
            dataGridConfigTable.Rows.Add(row);

            var dynamicList = new List<List<string>>();
            foreach (System.Data.DataColumn dc in dataGridConfigTable.Columns)
            {
                dynamicList.Add(dataGridConfigTable.AsEnumerable().Select(s => s.Field<string>(dc.ColumnName)).Where(x => x != null).ToList());
            }

            List<string> result = null;
            dynamicList.ForEach(x => BuildString(ref result, x));
            result.ForEach(i => Console.WriteLine(i));
            Console.ReadLine();
        }

        static void BuildString(ref List<string> param1List, List<string> param2List)
        {
            if (param1List == null)
            {
                param1List = param2List;
                return;
            }

            List<string> result = new List<string>();
            param1List.ForEach(x => param2List.ForEach(y => result.Add(String.Format("{0} - {1}", x, y))));
            param1List = result;

        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM