What is the shortest code to get surrounding coordinates?

六眼飞鱼酱① 提交于 2019-12-23 09:55:48

问题


I don't like my following implementation of surroundingPositions to get the x- and y-Coordinates surrounding a specific position, because in my opinion it is too long for the simple intent and it has a pyramid of doom structure.

struct Position: CustomStringConvertible {

    let x, y: Int

    var surroundingPositions: [Position] {
        var surroundingPositions: [Position] = []
        for x in (self.x - 1)...(self.x + 1) {
            for y in (self.y - 1)...(self.y + 1) {
                if !(x == self.x && y == self.y) {
                    surroundingPositions.append(Position(x: x, y: y))
                }
            }
        }
        return surroundingPositions
    }

    var description: String {
        return "(\(x),\(y))"
    }

}

Usage:

let testPosition = Position(x: 1, y: 1)
print(testPosition.surroundingPositions)
// Output: [(0,0), (0,1), (0,2), (1,0), (1,2), (2,0), (2,1), (2,2)]

What is the shortest way to implement this with the same (correct) result? I'm thinking of functions like map, filter, reduce, etc., but can't find the right combination so far ...


回答1:


Well, you could always hardcode it. Here, I hardcoded the deltas and create a new Position for each delta:

var surroundingPositionsHardcoded: [Position] {
    let deltas: [(Int, Int)] = [(-1, -1), (-1, 0), (-1, +1), (0, -1), (0, +1), (+1, -1), (+1, 0), (+1, +1)]
    return deltas.map { Position(x: x+$0.0, y: y+$0.1) }
}

Or, you could compute the deltas using map. This has the added benefit that you could increase the surrounding distance.

var surroundingPositionsComputed: [Position] {
    let deltas = (-1...1).map { dx in (-1...1).map { dy in (dx, dy) } }
        .joined()
        .filter { $0.0 != 0 || $0.1 != 0 }
    return deltas.map { Position(x: x+$0.0, y: y+$0.1) }
}



回答2:


Since you only look for the neighbouring positions and seemingly have no constraint on x or y, you could save an array of (x, y) translations that each maps a given Position to one of its 8 different neighbouring ones.

struct Position: CustomStringConvertible {
    let x, y: Int

    // order of resulting neighbouring positions, given a position P
    // (1)  (2)  (3)
    // (4)  (P)  (5)
    // (6)  (7)  (8)
    private static let surroundingPositionsTranslations: [(x: Int, y: Int)] = [
        (-1, -1), (0, -1), (1, -1),
        (-1,  0),          (1,  0),
        (-1, -1), (0, -1), (1, -1)]

    var surroundingPositions: [Position] {
        return Position.surroundingPositionsTranslations
            .map { Position(x: x + $0.x, y: y + $0.y) }
    }

    var description: String {
        return "(\(x),\(y))"
    }
}

// Note that I've changed the order w.r.t. OP:s original code
// (modify the transfotmation above to modify the order)
let testPosition = Position(x: 1, y: 1)
print(testPosition.surroundingPositions)
// Output: [(0,0), (1,0), (2,0), (0,1), (2,1), (0,0), (1,0), (2,0)]


来源:https://stackoverflow.com/questions/44180840/what-is-the-shortest-code-to-get-surrounding-coordinates

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!