iOS Swift: Массив диапазона - PullRequest
       11

iOS Swift: Массив диапазона

0 голосов
/ 02 октября 2018

У меня есть класс Player, в котором хранится свойство rating типа Int:

class Player {
    typealias Rating: Int
    var rating: Rating = 0
}

. У меня есть различные экземпляры Range, которые указывают level для данного player находится по адресу:

private let level1Range = 0 ..< 100
private let level2Range = 100 ..< 500

Затем я могу switch на свойстве player rating получить уровень, на котором находится player:

switch rating {
case level1Range:
    print("On Level 1")
case level2Range:
    print("On Level 2")
default:
    break
} 

Я хочу быть в состоянии сказать, что такое следующий уровень и как далеко player от этого следующего уровня.

Я не уверен, что лучший способ выйтиЭта проблема.Я начал с создания массива:

private var ratingRanges: [Range] {
    return [level1Range, level2Range]
}

Но я получаю ошибку:

Ссылка на универсальный тип 'Range' требует аргументов в <...> Вставить '<<#Bound: Comparable # >> '

Если бы это сработало, то, я думаю, я мог бы найти первое ненулевое значение:

ratingRanges.first(where: { $0.min() - self.rating > 0 })

, чтобы найти следующий диапазон.

Или есть более эффективный способ для этого?

Спасибо за любую помощь

Ответы [ 3 ]

0 голосов
/ 02 октября 2018

Возможно, вам следует сохранить только максимальное значение диапазона.Например, вместо

private let level1Range = 0 ..< 100
private let level2Range = 100 ..< 500

вы можете использовать

private let level1MaxRating = 100
private let level2MaxRating = 500

и сравнить с

switch rating {
case 0...level1MaxRating:
    print("level 1")
case (level1MaxRating+1)...level2MaxRating:
    print("level 2")
}
0 голосов
/ 02 октября 2018

Мое решение - создать Уровень enum:

    enum Level: Int {
    case level1 = 1
    case level2

    init?(rating: Int) {
        switch rating {
        case Level.level1.range:
            self = .level1
        case Level.level2.range:
            self = .level2
        default:
            return nil
        }
    }

    var range: CountableRange<Int> {
        switch self {
        case .level1:
            return level1Range
        case .level2:
            return level2Range
        }
    }
}

И тогда все, что вам нужно сделать, это добавить следующие методы в ваш Player класс:

func nextLevel() -> Level? {
    guard let currentLevel = Level(rating: rating) else {
        return nil
    }
    guard let nextLevel = Level(rawValue: currentLevel.rawValue + 1) else {
        return nil
    }
    return nextLevel
}

func distanceTo(level: Level) -> Int {
    let levelLowerBound = level.range.lowerBound
    return levelLowerBound - rating
}
0 голосов
/ 02 октября 2018

Вам необходимо предоставить общий тип заполнителя для Range:

private var ratingRanges: [Range<Rating>] {
    return [level1Range, level2Range]
}

или проще, с автоматическим выводом типа, в качестве (ленивого) хранимого свойства:

private lazy var ratingRanges = [level1Range, level2Range]

Определение следующего диапазона может быть сделано как

func nextRange() -> Range<Rating>? {
    return ratingRanges.first(where: { $0.lowerBound > rating})
}
...