Объединение двух таблиц (представленных IEnumerable ) с разными столбцами - PullRequest
2 голосов
/ 26 апреля 2020

Моя таблица \ класс сетки представлена ​​двумя свойствами:

public class MyTable 
{ 
   public IEnumerable<string> Columns {get;set;} 
   public IEnumerable<IEnumerable<string>> Rows {get;set;} 
}

Итак, допустим, у меня есть следующая таблица \ grid:

ColumnA ColumnB Column C
A1   B1   C1
A2   B2   C2
A3   B3   C3

Она будет представлена ​​этими двумя свойства следующие:

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"),
};

До сих пор объединение двух таких таблиц было очень простым и эффективным, я просто использовал «Concat ()» между их свойствами Rows и получил их таблицу «Merged» со всеми data.

Теперь мой вопрос: если мне нужно объединить две такие таблицы с различными столбцами , как я могу объединить их наиболее эффективным способом? ?

Пример объединения с разными столбцами:

  1. Первая таблица:
ColumnA ColumnB Column C
A1   B1   C1
A2   B2   C2
A3   B3   C3
Второй стол:
ColumnB Column D
B4   D4
B5   D5
B6   D6
Их "объединенная" таблица должна быть:
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

И, конечно, она должна быть представлена ​​свойствами "Columns" и "Rows" следующим образом:

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"}
};

Какой самый эффективный способ сделать это?

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 26 апреля 2020

Это идея, которую я придумал.

вы можете сделать это с помощью двумерного массива, но, на мой взгляд, код выглядит ужасно.

 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);
            }
        }
    }
0 голосов
/ 26 апреля 2020

Я не совсем уверен, что это за приложение, но в идеале вы хотели бы воспользоваться преимуществами безопасности типа C#. Коллекция строк не является типобезопасной.

При этом C# позволяет создавать коллекции с объектами разных типов с использованием ключевого слова Dynami c.

Рассмотрим следующие типы объектов:

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;}
}

С этими типами в руках вы можете использовать ключевое слово dynamici c, чтобы сделать следующее:

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}");
}

Если у вас абсолютно на go маршрут сбора строк, тогда ключевое слово Dynami c будет по-прежнему работать.

Я создал скрипту do tnet, чтобы вы могли увидеть это в действии: https://dotnetfiddle.net/lyucN2.

-Isaa c

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...