Обновлен ответ для преобразования любого Int в массив степеней 2. Раскомментируйте фатальную ошибку, если вы хотите, чтобы она вылетала при отрицательных значениях
enum State: Int {
case illegal = -1
case readyButton = 1
case workingButton = 2
case sleepingButton = 4
}
Вот общее решение для разложения целых чисел на степени 2:
extension Int {
func toPowersOf2() -> [Int] {
guard self > 0 else {
// fatalError("The number should be strictly positive")
print("The number should be strictly positive")
return [-1] //not really - use fatal error above to enforce crash if you don't want this behavior
}
var arrayOfPowers: [Int] = [] //Will hold the desired powers
var remainder: Int = self //We will substract found powers from the original number
//Since Ints are coded on 64 bits (the 64th is for the sign)
//Let's create an array of all the powers of 2 that
//could be used to decompose an integer
let powers = (0...62).map { NSDecimalNumber(decimal: pow(2.0, $0)).intValue }
//Let's go from the highest to the lowest power
for i in (0 ..< powers.count).reversed() {
//Here we are looking for the power just smaller than the remainder
if i < powers.count - 1, powers[i] <= remainder, powers[i + 1] > remainder {
let p = powers[i]
arrayOfPowers.append(p)
remainder -= p
}
//if this is the biggest power and it is smaller than the number, then add it to arrayOfPowers
else if i == powers.count - 1, powers[i] <= remainder {
let p = powers[i]
arrayOfPowers.append(p)
}
}
return arrayOfPowers
}
func toStateArray() -> [State] {
let array = self.toPowersOf2().map{ State(rawValue: $0) }.filter{ $0 != nil }
return array as! [State]
}
}
И вы можете использовать это так:
(-1).toStateArray()//[illegal]
0.toStateArray() //[illegal]
7.toPowersOf2() //[4, 2, 1]
7.toStateArray() //[sleepingButton, workingButton, readyButton]