C# 合并具有不同列的两个表(由IEnumerable<;IEnumerable<;string>;)之间

C# 合并具有不同列的两个表(由IEnumerable<;IEnumerable<;string>;)之间,c#,.net,performance,C#,.net,Performance,My table\grid类由两个属性表示: public class MyTable { public IEnumerable<string> Columns {get;set;} public IEnumerable<IEnumerable<string>> Rows {get;set;} } 它将由以下两个属性表示: Columns = new List<string> {"ColumnA", "ColumnB", "C

My table\grid类由两个属性表示:

public class MyTable 
{ 
   public IEnumerable<string> Columns {get;set;} 
   public IEnumerable<IEnumerable<string>> Rows {get;set;} 
}
它将由以下两个属性表示:

Columns = new List<string> {"ColumnA", "ColumnB", "ColumnC"};
Rows = new List<IEnumerable<string>>
{
  new List<string>("A1", "B1", "C1"),
  new List<string>("A2", "B2", "C2"),
  new List<string>("A3", "B3", "C3"),
};
Columns = new List<string> {"ColumnA", "ColumnB", "ColumnC", "ColumnD"};

Rows = new List<IEnumerable<string>>
{
  new List<string>{"A1", "B1", "C1", null},
  new List<string>{"A2", "B2", "C2", null},
  new List<string>{"A3", "B3", "C3", null},
  new List<string>{null, "B4", null, "D4"},
  new List<string>{null, "B5", null, "D5"},
  new List<string>{null, "B6", null, "D6"}
};
  • 第二张表:
  • 其“合并”表应为:
  • 当然,它需要用“列”和“行”属性表示,如下所示:

    Columns = new List<string> {"ColumnA", "ColumnB", "ColumnC"};
    Rows = new List<IEnumerable<string>>
    {
      new List<string>("A1", "B1", "C1"),
      new List<string>("A2", "B2", "C2"),
      new List<string>("A3", "B3", "C3"),
    };
    
    Columns = new List<string> {"ColumnA", "ColumnB", "ColumnC", "ColumnD"};
    
    Rows = new List<IEnumerable<string>>
    {
      new List<string>{"A1", "B1", "C1", null},
      new List<string>{"A2", "B2", "C2", null},
      new List<string>{"A3", "B3", "C3", null},
      new List<string>{null, "B4", null, "D4"},
      new List<string>{null, "B5", null, "D5"},
      new List<string>{null, "B6", null, "D6"}
    };
    
    Columns=新列表{“ColumnA”、“ColumnB”、“ColumnC”、“ColumnD”};
    行=新列表
    {
    新列表{“A1”、“B1”、“C1”、null},
    新列表{“A2”、“B2”、“C2”、null},
    新列表{“A3”、“B3”、“C3”、null},
    新列表{null,“B4”,null,“D4”},
    新列表{null,“B5”,null,“D5”},
    新列表{null,“B6”,null,“D6”}
    };
    
    最有效的方法是什么


    提前感谢。

    我不完全确定此应用程序是什么,但理想情况下,您希望利用C#的类型安全性。字符串集合不是类型安全的

    也就是说,C#允许您使用Dynamic关键字创建具有不同类型对象的集合

    考虑以下对象类型:

    public class Class1 {
        public string ColumnA {get;set;} 
        public string ColumnB {get;set;}
        public string ColumnC {get;set;}
    }
    
    public class Class2 {
        public string ColumnD {get;set;} 
        public string ColumnE {get;set;}
        public string ColumnF {get;set;}
    }
    
    有了这些类型,您可以使用dynamic关键字执行以下操作:

    var list = new List<dynamic>();
    list.Add(new Class1(){ColumnA = "TestColumnA"});
    list.Add(new Class2(){ColumnD = "TestColumnD"});
    Console.WriteLine(list[0].ColumnA.ToString());
    Console.WriteLine(list[1].ColumnD.ToString());
    for(var i =0; i< list.Count; i++)
    {
      Console.WriteLine(list[i].GetType().Name);            
      Console.WriteLine($"IsComponentA: {list[i] is Class1}");
    }
    
    var list=newlist();
    Add(new Class1(){ColumnA=“TestColumnA”});
    添加(新类2(){ColumnD=“TestColumnD”});
    Console.WriteLine(列表[0].ColumnA.ToString());
    Console.WriteLine(列表[1]。ColumnD.ToString());
    对于(var i=0;i
    如果您必须执行字符串收集路径,那么Dynamic关键字仍然有效

    我创建了一个dotnet提琴,这样您就可以看到它的作用:


    -艾萨克这是我想到的主意

    你可以用一个二维数组来代替,但在我看来,这会让代码很难看

     static void Main(string[] args)
        {
            MyTable table1 = new MyTable
            {
                Columns = new List<string> { "ColumnA", "ColumnB", "ColumnC" },
                Rows = new List<IEnumerable<string>>
                {
                    new List<string> {"A1", "B1", "C1"},
                    new List<string> {"A2", "B2", "C2"},
                    new List<string> {"A3", "B3", "C3"}
                }
            };
            MyTable table2 = new MyTable
            {
                Columns = new List<string> { "ColumnB", "ColumnD" },
                Rows = new List<IEnumerable<string>>
                {
                    new List<string> {"B1","D1"},
                    new List<string> {"B2","D2"},
                    new List<string> {"B3","D3"}
                }
            };
            var result = Merge(table1, table2);
        }
    
        private static MyTable Merge(MyTable table1, MyTable table2)
        {
            Dictionary<string, List<string>> tempTable = new Dictionary<string, List<string>>();
    
            AddColumns(tempTable, table1);
            AddColumns(tempTable, table2);
            AppendToTable(table1, tempTable);
            AppendToTable(table2, tempTable);
    
            return ConvertToTable(tempTable);
        }
        private static void AddColumns(Dictionary<string, List<string>> tempTable, MyTable table1)
        {
            foreach (var column in table1.Columns)
            {
                tempTable[column] = new List<string>();
            }
        }
        private static MyTable ConvertToTable(Dictionary<string, List<string>> tempTable)
        {
            MyTable newTable = new MyTable();
            var maxIndex = tempTable.ElementAt(0).Value.Count;
    
            newTable.Rows = new List<IEnumerable<string>>();
            for (int index = 0; index < maxIndex; index++)
            {
                var newRow = new List<string>();
                foreach (var row in tempTable.Values)
                {
                    newRow.Add(row[index]);
                }
                newTable.Rows = newTable.Rows.Append(newRow);
            }
            newTable.Columns = tempTable.Keys;
            return newTable;
        }
        private static void AppendToTable(MyTable table1, Dictionary<string, List<string>> tempTable)
        {
            int rowIndex = tempTable.First().Value.Count + 1;
            foreach (var row in table1.Rows)
            {
                for (int cellIndex = 0; cellIndex < row.Count(); cellIndex++)
                {
                    string columnName = table1.Columns.ElementAt(cellIndex);
                    tempTable[columnName].Add(row.ElementAt(cellIndex));
                }
    
                FillEmptyCells(tempTable, rowIndex);
    
                rowIndex++;
            }
        }
        private static void FillEmptyCells(Dictionary<string, List<string>> tempTable, int rowIndex)
        {
            foreach (var row in tempTable.Values)
            {
                if (row.Count < rowIndex)
                {
                    row.Add(null);
                }
            }
        }
    
    static void Main(字符串[]args)
    {
    MyTable1=新的MyTable
    {
    Columns=新列表{“ColumnA”、“ColumnB”、“ColumnC”},
    行=新列表
    {
    新列表{“A1”、“B1”、“C1”},
    新列表{“A2”、“B2”、“C2”},
    新列表{“A3”、“B3”、“C3”}
    }
    };
    MyTable 2=新的MyTable
    {
    Columns=新列表{“ColumnB”,“ColumnD”},
    行=新列表
    {
    新列表{“B1”、“D1”},
    新列表{“B2”,“D2”},
    新列表{“B3”,“D3”}
    }
    };
    var结果=合并(表1、表2);
    }
    私有静态MyTable合并(MyTable表1、MyTable表2)
    {
    Dictionary tentable=新字典();
    AddColumns(表1);
    AddColumns(表2);
    可追加(表1,可追加);
    可追加(表2,可追加);
    返回可转换(可诱惑);
    }
    私有静态void AddColumns(Dictionary-tentable,MyTable1)
    {
    foreach(表1.Columns中的var列)
    {
    可诱惑的[列]=新列表();
    }
    }
    私有静态MyTable可转换(字典可转换)
    {
    MyTable newTable=新MyTable();
    var maxIndex=tentable.ElementAt(0).Value.Count;
    newTable.Rows=新列表();
    对于(int index=0;index
    如果您实际有
    模型
    类来表示您的data@zaitsman您可以假设这两个属性位于“MyTable”类中。@Nurial ZRUBALI mena更像是
    公共类模型{public string Column1{get;set;}}
    或类似内容。@zaitsman,如我所说,您可以假设有:公共类MyTable{public IEnumerable Columns{get;set;}公共IEnumerable Rows{get;set;}我现在也更新了我的问题accordingly@Trevor里德,你能再看一遍我的问题文本吗?我做了一些改变。提前谢谢。@Issac Martinez谢谢,但我不明白它是如何解决我的问题的:)我需要一个合并两个这样的表的代码:)
    var list = new List<dynamic>();
    list.Add(new Class1(){ColumnA = "TestColumnA"});
    list.Add(new Class2(){ColumnD = "TestColumnD"});
    Console.WriteLine(list[0].ColumnA.ToString());
    Console.WriteLine(list[1].ColumnD.ToString());
    for(var i =0; i< list.Count; i++)
    {
      Console.WriteLine(list[i].GetType().Name);            
      Console.WriteLine($"IsComponentA: {list[i] is Class1}");
    }
    
     static void Main(string[] args)
        {
            MyTable table1 = new MyTable
            {
                Columns = new List<string> { "ColumnA", "ColumnB", "ColumnC" },
                Rows = new List<IEnumerable<string>>
                {
                    new List<string> {"A1", "B1", "C1"},
                    new List<string> {"A2", "B2", "C2"},
                    new List<string> {"A3", "B3", "C3"}
                }
            };
            MyTable table2 = new MyTable
            {
                Columns = new List<string> { "ColumnB", "ColumnD" },
                Rows = new List<IEnumerable<string>>
                {
                    new List<string> {"B1","D1"},
                    new List<string> {"B2","D2"},
                    new List<string> {"B3","D3"}
                }
            };
            var result = Merge(table1, table2);
        }
    
        private static MyTable Merge(MyTable table1, MyTable table2)
        {
            Dictionary<string, List<string>> tempTable = new Dictionary<string, List<string>>();
    
            AddColumns(tempTable, table1);
            AddColumns(tempTable, table2);
            AppendToTable(table1, tempTable);
            AppendToTable(table2, tempTable);
    
            return ConvertToTable(tempTable);
        }
        private static void AddColumns(Dictionary<string, List<string>> tempTable, MyTable table1)
        {
            foreach (var column in table1.Columns)
            {
                tempTable[column] = new List<string>();
            }
        }
        private static MyTable ConvertToTable(Dictionary<string, List<string>> tempTable)
        {
            MyTable newTable = new MyTable();
            var maxIndex = tempTable.ElementAt(0).Value.Count;
    
            newTable.Rows = new List<IEnumerable<string>>();
            for (int index = 0; index < maxIndex; index++)
            {
                var newRow = new List<string>();
                foreach (var row in tempTable.Values)
                {
                    newRow.Add(row[index]);
                }
                newTable.Rows = newTable.Rows.Append(newRow);
            }
            newTable.Columns = tempTable.Keys;
            return newTable;
        }
        private static void AppendToTable(MyTable table1, Dictionary<string, List<string>> tempTable)
        {
            int rowIndex = tempTable.First().Value.Count + 1;
            foreach (var row in table1.Rows)
            {
                for (int cellIndex = 0; cellIndex < row.Count(); cellIndex++)
                {
                    string columnName = table1.Columns.ElementAt(cellIndex);
                    tempTable[columnName].Add(row.ElementAt(cellIndex));
                }
    
                FillEmptyCells(tempTable, rowIndex);
    
                rowIndex++;
            }
        }
        private static void FillEmptyCells(Dictionary<string, List<string>> tempTable, int rowIndex)
        {
            foreach (var row in tempTable.Values)
            {
                if (row.Count < rowIndex)
                {
                    row.Add(null);
                }
            }
        }