Với Swift 3, khi bạn có một đối tượng phù hợp với Sequence
giao thức và bạn muốn liên kết từng phần tử bên trong nó với chỉ mục của nó, bạn có thể sử dụng enumerated()
phương thức.
Ví dụ:
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")]
Do đó, trong trường hợp đơn giản nhất, bạn có thể triển khai thuật toán Luhn trong Sân chơi như sau:
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
Nếu bạn bắt đầu từ a String
, bạn có thể thực hiện nó như thế này:
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
Nếu bạn cần lặp lại các thao tác đó, bạn có thể cấu trúc lại mã của mình thành một phần mở rộng:
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
Hoặc, theo một cách ngắn gọn:
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