2013-08-20 2 views
2

установкиСоздания многослойной матрицы-иш Коллекции в C#

У меня есть List<Room>(), которые я получаю назад от службы. Список обновляется каждые 10 секунд, а номера добавляются и удаляются.

class Room 
{ 
    public int ID {get;set;} 
} 

Моя работа

Чтобы отобразить эти номера на экране, у меня есть матрицы, как вид переменного размера. Иногда матрица 3 x 3 ячейки, иногда это 4 x 2 или 5 x 1.

Мне нужен был способ «запомнить», какой слот/ячейку помещали в комнату, поэтому я подумал, что DataTable дал бы мне этот вариант.

Чтобы сохранить клетки, которые я использую в DataTable, который имеет 3 колонки:

  • "Колонка" (INT)
  • "Row" (INT)
  • "Номер" (номер)

Итак, если у меня есть матрица 2 x 4, это будет выглядеть так.

 

Column | Row | Room 
----------------------------- 
    0 | 0 | rooms[0] 
----------------------------- 
    1 | 0 | rooms[1] 
----------------------------- 
    2 | 0 | rooms[2] 
----------------------------- 
    0 | 1 | rooms[3] 
----------------------------- 
    1 | 2 | rooms[4] 

And so forth... 

После того, как у меня есть этот DataTable я тогда в состоянии обновить экран, зная, что каждый номер будет отображаться в положении это было раньше. Это, вероятно, может быть достигнуто умнее.

Проблема

Теперь мне нужно перечислить List<Room> и заполнить матрицу/DataTable.

Если у меня больше комнат, чем ячеек, то мне нужно снова начать с позиции 0,0 (например, добавить новую матрицу в качестве слоя), пока всем комнатам не будет назначена ячейка.

подход до сих пор

Я попробовал несколько for(...) петель, которые выглядят как:

int totalTiles = area.TileColumns * area.TileRows; 
int totalLayers = (int)Math.Ceiling((double)area.Rooms.Count/totalTiles); 

for (int i = 0; i < totalLayers; i++) 
{ 
    for (int j = 0; j < area.TileRows; j++) 
    { 
     for (int k = 0; k < area.TileColumns; k++) 
     { 
      // This is going nowhere :-(
     } 
    } 
} 

В моем мозгу

Когда я впервые наткнулся на эту проблему, я сразу подумал: «Ничего простого запроса LINQ не исправит!». И затем я кирпич ...

Что было бы самым эффективным/наилучшим способом для заполнения этой матрицы?

+1

но ** в моем мозгу **: * LINQ не всегда может делать вещи, особенно все, что связано с настройкой/изменением не получения/запроса * –

+2

Вы не должны использовать 'DataTable' для представления матрицы. Во-первых, это довольно «тяжелый» объект, а не легкий. Затем он предназначен для представления ряда строк, что не совсем то же самое, что и матрица nxm. Одним из главных следствий этого является то, что вы не устанавливаете действительно отдельные ячейки, вы устанавливаете строки. Вам, вероятно, лучше всего с помощью многомерной матрицы. – Servy

ответ

1

Не имея возможности сделать предположения, как изменится строка/столбцы во время выполнения, я должен сказать, просто сделайте ее полностью динамичной.

class RoomStorage 
{ 
    public Room room {get;set;} 
    public int layer {get;set;} 
    public int row {get;set;} 
    public int col {get;set;} 
} 

var matrix=new List<RoomStorage>(); 

Тогда вы можете что-то вроде:

var newRooms=new List<Room>(); // Get from service 

//Remove rooms no longer in use 
var matrix=matrix.Where(m=>newRooms.Select(nr=>nr.ID).Contains(m.Room.ID)); 

//Find rooms we need to add (Optionally use Exclude for faster perf) 
var roomsToAdd=newRooms.Where(r=>matrix.Select(m=>m.Room.ID).Contains(r.ID)); 

var maxLayer=matrix.Max(m=>m.layer); 
var rows = ? 
var cols = ? 

var positions=Enumerable 
    .Range(0,maxLayer+1) 
    .SelectMany(layer=> 
     Enumerable 
     .Range(0,rows) 
     .SelectMany(row=> 
      Enumerable 
       .Range(0,cols) 
       .Select(col=>new {layer,row,col}))); 

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

Смежные вопросы