2

设置

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

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

我的工作

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

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

为了存储单元格,我使用了一个 DataTable,它有 3 列:

  • “列”(整数)
  • “行”(整数)
  • “房间”(房间)

所以如果我有一个 2 x 4 矩阵,它看起来像这样。

 专栏 | 行 | 房间
-----------------------------------------
    0 | 0 | 房间[0]
-----------------------------------------
    1 | 0 | 房间[1]
-----------------------------------------
    2 | 0 | 房间[2]
-----------------------------------------
    0 | 1 | 房间[3]
-----------------------------------------
    1 | 2 | 房间[4]

等等……

一旦我有了这个 DataTable,我就可以刷新屏幕,因为我知道每个房间都将显示在它之前的位置。这可能以更智能的方式实现。

问题

现在我需要枚举List<Room>并填充矩阵/数据表。

如果我的房间多于单元格,那么我需要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 查询解决不了的!” . 然后我变砖了...

填充此矩阵的最有效/最佳执行方法是什么?

4

1 回答 1

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

然后您可以使用位置,将其左连接到矩阵以进行显示,或找到第一个空位置。

于 2013-08-22T16:28:17.050 回答