Is there any "Swifty sugar" that could simplify the following?
let x: Int
let sign: FloatingPointSign
if let p = signedPositiveValues.index(of: c) {
x = p
sign = .plus
}
else if let n = signedNegativeValues.index(of: c) {
x = n
sign = .minus
}
else {
return nil
}
Any thoughts on the "Swiftyness" of this full example?
import Foundation
extension Collection {
public var finalIndex: Self.Index {
return self.index(self.endIndex, offsetBy: -1)
}
}
extension Decimal {
public enum SignPosition {
case none, leading, trailing
}
// scale: Scale is the number of digits to the right of the decimal point in a number.
public init?(digitString digits: String, signPosition: SignPosition = .none, scale: Int = 0) {
// make sure digit string is not an empty string
guard let firstDigit = digits.first, let lastDigit = digits.last else { return nil }
var digitsWithSign: (String, FloatingPointSign)? {
let digit: Character
let digitPos: String.Index
switch signPosition {
case .none:
return (digits, .plus)
case .leading:
(digit, digitPos) = (firstDigit, digits.startIndex)
case .trailing:
(digit, digitPos) = (lastDigit, digits.finalIndex)
}
let signedPositiveDigits = [Character]("{ABCDEFGHI")
let signedNegativeDigits = [Character]("}JKLMNOPQR")
let sign: FloatingPointSign
let digitValue: Int
if let p = signedPositiveDigits.index(of: digit) {
digitValue = p
sign = .plus
}
else if let n = signedNegativeDigits.index(of: digit) {
digitValue = n
sign = .minus
}
else {
return nil // sign position does not have a valid "sign digit"
}
var unsignedString = digits
unsignedString.replaceSubrange(digitPos ... digitPos, with: String(digitValue))
return (unsignedString, sign)
}
guard let (digits, sign) = digitsWithSign else { return nil }
guard let significand = Decimal(string: digits) else { return nil }
self = Decimal(sign: sign, exponent: 0 - scale, significand: significand)
}
}
if let d = Decimal(digitString: "201", scale: 2) {
print(d) // 2.01
}
if let d = Decimal(digitString: "R87", signPosition: .leading, scale: 2) {
print(d) // -9.87
}
if let d = Decimal(digitString: "21{", signPosition: .trailing, scale: 2) {
print(d) // 2.1
}