Swift 3では、Sequence
プロトコルに準拠するオブジェクトがあり、その内部の各要素をインデックスにリンクする場合は、次のように使用できます。enumerated()
メソッド。
例えば:
let array = [1, 18, 32, 7]
let enumerateSequence = array.enumerated() // type: EnumerateSequence<[Int]>
let newArray = Array(enumerateSequence)
print(newArray) // prints: [(0, 1), (1, 18), (2, 32), (3, 7)]
let reverseRandomAccessCollection = [1, 18, 32, 7].reversed()
let enumerateSequence = reverseRandomAccessCollection.enumerated() // type: EnumerateSequence<ReverseRandomAccessCollection<[Int]>>
let newArray = Array(enumerateSequence)
print(newArray) // prints: [(0, 7), (1, 32), (2, 18), (3, 1)]
let reverseCollection = "8763".characters.reversed()
let enumerateSequence = reverseCollection.enumerated() // type: EnumerateSequence<ReverseCollection<String.CharacterView>>
let newArray = enumerateSequence.map { ($0.0 + 1, String($0.1) + "A") }
print(newArray) // prints: [(1, "3A"), (2, "6A"), (3, "7A"), (4, "8A")]
したがって、最も単純なケースでは、次のようにプレイグラウンドでLuhnアルゴリズムを実装できます。
let array = [8, 7, 6, 3]
let reversedArray = array.reversed()
let enumerateSequence = reversedArray.enumerated()
let luhnClosure = { (sum: Int, tuple: (index: Int, value: Int)) -> Int in
let indexIsOdd = tuple.index % 2 == 1
guard indexIsOdd else { return sum + tuple.value }
let newValue = tuple.value == 9 ? 9 : tuple.value * 2 % 9
return sum + newValue
}
let sum = enumerateSequence.reduce(0, luhnClosure)
let bool = sum % 10 == 0
print(bool) // prints: true
から始める場合はString
、次のように実装できます。
let characterView = "8763".characters
let mappedArray = characterView.flatMap { Int(String($0)) }
let reversedArray = mappedArray.reversed()
let enumerateSequence = reversedArray.enumerated()
let luhnClosure = { (sum: Int, tuple: (index: Int, value: Int)) -> Int in
let indexIsOdd = tuple.index % 2 == 1
guard indexIsOdd else { return sum + tuple.value }
let newValue = tuple.value == 9 ? 9 : tuple.value * 2 % 9
return sum + newValue
}
let sum = enumerateSequence.reduce(0, luhnClosure)
let bool = sum % 10 == 0
print(bool) // prints: true
これらの操作を繰り返す必要がある場合は、コードを拡張機能にリファクタリングできます。
extension String {
func luhnCheck() -> Bool {
let characterView = self.characters
let mappedArray = characterView.flatMap { Int(String($0)) }
let reversedArray = mappedArray.reversed()
let enumerateSequence = reversedArray.enumerated()
let luhnClosure = { (sum: Int, tuple: (index: Int, value: Int)) -> Int in
let indexIsOdd = tuple.index % 2 == 1
guard indexIsOdd else { return sum + tuple.value }
let newValue = tuple.value == 9 ? 9 : tuple.value * 2 % 9
return sum + newValue
}
let sum = enumerateSequence.reduce(0, luhnClosure)
return sum % 10 == 0
}
}
let string = "8763"
let luhnBool = string.luhnCheck()
print(luhnBool) // prints: true
または、非常に簡潔な方法で:
extension String {
func luhnCheck() -> Bool {
let sum = characters
.flatMap { Int(String($0)) }
.reversed()
.enumerated()
.reduce(0) {
let indexIsOdd = $1.0 % 2 == 1
guard indexIsOdd else { return $0 + $1.1 }
return $0 + ($1.1 == 9 ? 9 : $1.1 * 2 % 9)
}
return sum % 10 == 0
}
}
let string = "8763"
let luhnBool = string.luhnCheck()
print(luhnBool) // prints: true