首页 > 解决方案 > 有没有比嵌套循环更好的方法?

问题描述

我有以下代码:

(0...engine.rows-1).forEach {row in
        (0...engine.cols-1).forEach {col in
            //print("(\(row),\(col)) state = \(engine.grid[(row,col)])")
            switch engine.grid[(row,col)] {
            case CellState.empty: emptyCount = emptyCount + 1
            case CellState.alive: aliveCount = aliveCount + 1
            case CellState.died: diedCount = diedCount + 1
            case CellState.born: bornCount = bornCount + 1
            }
        }
    }

看起来过滤器可以更有效地做到这一点,但我不理解复杂对象的语法。如果没有过滤器,是否有更好的方法来快速执行嵌套循环?

谢谢

标签: swiftswift3

解决方案


这看起来像康威的生命游戏

您正在循环计算各种细胞状态的网格。嵌套循环是执行此操作的自然方式。我建议使用for in而不是forEach. 另外,我建议创建一个字典来保存计数:

// Create dictionary to hold counts
var counts: [CellState : Int] = [.alive: 0, .died: 0, .born: 0, .empty: 0]

for row in 0 ..< engine.rows {
    for col in 0 ..< engine.cols {
        //print("(\(row),\(col)) state = \(engine.grid[(row,col)])")
        counts[engine.grid[(row, col)]] += 1
    }
}

另一种方式:

您没有向我们提供有关您的Engine class或的信息struct。根据 的实现grid,可能有一种方法可以获取所有单元格的数组。

例如,如果您使用N 维数组来创建grid,那么您可以将所有单元格作为一个带有 的数组来获取grid.data

struct Engine {
    let rows: Int
    let cols: Int
    var grid: NDimArray<CellState>

    init(rows: Int, cols: Int) {
        self.rows = rows
        self.cols = cols
        self.grid = NDimArray<CellState>(dimensions: rows, cols, initial: CellState.empty)
    } 
}

设置单元格状态如下所示:

var engine = Engine(rows: 20, cols: 20)
engine.grid[0, 0] = .alive
engine.grid[0, 1] = .alive

然后计算单元格类型的代码变为:

var counts: [CellState : Int] = [.alive: 0, .died: 0, .born: 0, .empty: 0]
engine.grid.data.forEach { cell in counts[cell] += 1 }

推荐阅读