簡體   English   中英

查找數組元素索引的更好方法?

[英]Better way to find array element index?

我對 Swift 和一般編程比較陌生。

我正在處理一個帶有二維數組的項目來表示我在其中存儲自定義對象的網格:

class Grid {
    var element: [[GridElement]]
}

我經常需要通過其坐標訪問元素。 前任:

let gridElement = grid.element[coord.x][coord.y]

我還需要經常從給定的 gridElement(它在 2d 數組中的索引)獲取坐標。 這導致嵌套循環似乎不是最快或最優雅的解決方案:

func getCoord(_ gridElement: GridElement) -> Coord {
    for x in 0..<xSize {
        for y in 0..<ySize {
            if element[x][y] == gridElement { return Coord(x: x, y: y) }
        }
    }
    return Coord(x: -1, y: -1)
}

因為我希望它與大網格一起順利工作,所以這看起來不是一個解決方案。 我錯過了一些簡單的東西嗎?

我正在考慮將坐標存儲在 GridElement 對象本身中,但這也感覺像是糟糕的設計,因為當 GridElement 更改位置時,我需要不斷更新它。

這更像是一個設計/架構問題,而不是尋找一個神奇的功能來解決我的問題。 感覺應該建立雙向參考的設計模式,但我無法找到答案。 有什么建議嗎?

我正在考慮將坐標存儲在 GridElement 對象本身中,但這也感覺像是糟糕的設計,因為當 GridElement 更改位置時,我需要不斷更新它。

我認為這樣的事情是一個可行的解決方案。 您可以將坐標存儲在另一個字典中,而不是將其存儲在網格元素對象中:

private var gridElementPositionDict: [GridElement: Coord]

正如您所說,這將要求您在網格元素更改位置時不斷設置gridElementPositionDict的值。 但是,您可以使用一些封裝,以便只將它們設置在一個地方。

首先,將您的elements數組設為private ,並為您的Grid類添加一個帶有兩個參數的subscript 下標將接受Coord以訪問特定位置的特定網格元素。 在這個下標的 setter 中,你可以修改gridElementPositionDict來設置GridElement的新位置。

然后,您可以編寫另一個方法(或下標)來接受返回其位置的GridPosition

您還可以添加諸如swapElements(at:and:)changeElementPositon(_:to:)等方法。這都是關於封裝您的數據結構。

下面是一些代碼作為示例:

class Grid<T: Hashable> {
    private var elements: [[T?]]
    private var elementsPositionDict: [T: Coord]

    init() {
        elements = [
            [nil, nil, nil, nil],
            [nil, nil, nil, nil],
            [nil, nil, nil, nil],
            [nil, nil, nil, nil],
        ]
        elementsPositionDict = [:]
    }

    subscript(_ coord: Coord) -> T? {
        get { return elements[coord.x][coord.y] }
        set {
            // this is the ONLY place you modify the dictionary
            if let oldValue = elements[coord.x][coord.y] {
                elementsPositionDict[oldValue] = nil
            }
            elements[coord.x][coord.y] = newValue
            if let v = newValue {
                elementsPositionDict[v] = coord
            }
        }
    }

    func coord(of element: T) -> Coord? {
        return elementsPositionDict[element]
    }
}

我認為你的getCoord函數應該是這樣的:

func getCoord(_ gridElement: GridElement) -> Coord {
    for (i, row) in element.enumerated() {
        if let index = row.firstIndex(of: gridElement) {
            return Coord(x: i, y: index)
        }
    }
    return Coord(x: -1, y: -1)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM