在C#中创建多层matrix-ish集合

时间:2013-08-20 13:58:59

标签: c# linq loops datatable ienumerable

设置

我有一个List<Room>()我从服务中回来了。该列表每10秒刷新一次,并添加和删除房间。

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

我的工作

要在屏幕上显示这些房间,我有一个可变大小的类似Matrix的视图。 有时矩阵是3 x 3个单元格,有时则是4 x 2或5 x 1。

我需要一种“记住”房间放置在哪个插槽/单元格的方法,所以我认为DataTable会给我这个选项。

要存储单元格,我使用DataTable,它有3列:

  • “Column”(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 个答案:

答案 0 :(得分: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})));

然后你可以使用位置,将它连接到矩阵以便显示,或者找到第一个空位。