C# 合并具有不同列的两个表(由IEnumerable<;IEnumerable<;string>;)之间
My table\grid类由两个属性表示: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
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);
}
}
}