【问题标题】:Creating a multi-layered matrix-ish Collection in C#在 C# 中创建多层矩阵式集合
【发布时间】:2013-08-20 13:58:59
【问题描述】:

设置

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

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

我的工作

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

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

为了存储单元格,我使用了一个包含 3 列的 DataTable:

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

所以如果我有一个 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 查询解决不了的!”。然后我变砖了……

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

【问题讨论】:

  • 在我的大脑中LINQ 不能总是做这些事情,尤其是与设置/更改而不是获取/查询相关的任何事情
  • 您不应该使用DataTable 来表示矩阵。首先,它是一个相当“重”的物体,而不是一个轻量级的物体。接下来,它被设计为表示一系列行,这与 nxm 矩阵不太一样。这样做的一个主要后果是您没有设置真正的单个单元格,而是设置了行。只使用多维矩阵可能会更好。

标签: c# linq loops datatable ienumerable


【解决方案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})));

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-08
    • 2023-04-07
    • 1970-01-01
    • 2022-07-06
    • 2018-11-09
    • 1970-01-01
    • 2014-02-20
    • 1970-01-01
    相关资源
    最近更新 更多