将 return 类型更改为小数?

Changing return type to a decimal?

我正在尝试将我正在处理的当前值转换为百分之一。这是我的代码:

extension String {
    var value: Int {
        if let found = Array("abc".characters).indexOf(Character(lowercaseString)) {
            return found + 1
        }
        return 0
    }
    var totalValue: Int {
        var result = 0
        for letter in self.characters {
            result += String(letter).value
        }
        return result
    }
}

所以字母 a = .01,字母 b = .02,字母 c = .03

我要如何修改我的代码才能实现这种情况?

编辑

这是我使用的代码:

@IBAction func sum(sender: AnyObject) {
    strValue.text = String(format: "%.2f", "$\(strInput.text!.value.description)")
}

我不知道这是否是正确的方法,但就是这样

value 的 return 值除以 100?

extension String {
    var value: Float {
        if let found = Array("abc".characters).indexOf(Character(lowercaseString)) {
            return (Float(found + 1) / 100)
        }
        return 0
    }
    var totalValue: Float {
        var result: Float = 0
        for letter in self.characters {
            result += Float(String(letter).value)
        }
        return result
    }
}

"a".value // 0.01
"b".value // 0.02
"c".value // 0.03
"abc".totalValue // 0.06

要以小数点后三位显示每个值,请使用字符串格式:

String(format: "%.3f", "a".value) // "0.010"

或保留两位小数:

String(format: "%.2f", 0.1) // 0.10

字母字符到数值:使用模式匹配

如果您只想允许字母表中的字母进行这种字母 -> 十进制值转换,则对字符 "a" 到 [=15 的 unicode 标量使用模式匹配可能是合适的=].

另请注意,如果使用包含多个石墨烯簇(例如 "ab".value 在你的代码示例中会产生这样的错误)。因此,确定 .value 仅对单字符字符串真正“可用”是合适的;返回值 0,除了包含字母表字符的单字符字符串。

最后,Float 只是一个数字,将始终尽可能准确地显示(受浮点精度限制),但没有多余的小数,这就是为什么精确值的原因。 1/10 显示为 0.1 而不是 0.10。要控制要显示的小数位数,您需要将浮点数转换为 String,您可以在其中指定此转换中的格式,例如通过 String(format:) 初始值设定项,或者例如使用 NSNumberFormatter.

备选方案 #1:几个 String 扩展,如您自己的示例

下面是一个 String 扩展示例,使用模式匹配提取字母表中的(单个)字母的 Float .value 属性,还包括 String 这种值的表示,由 .valueAsString 调用(与 totalValue 相同;totalValueAsString)。

/* Alternative #1 */
extension String {

    var value: Float {
        guard case let uc = lowercaseString.unicodeScalars where uc.count == 1,
            let uc1 = uc.first where UnicodeScalar("a")..."z" ~= uc1 else {
            return 0
        }
        
        return Float(uc1.value-96)/100
    }
    
    var valueAsString: String {
        return String(format: "%.2f", self.value)
    }
    
    var totalValue: Float {
        var result: Float = 0
        for letter in self.characters {
            result += String(letter).value
        }
        return result
    }
    
    var totalValueAsString: String {
        return String(format: "%.2f", self.totalValue)
    }
    
}

/* example usage */
"a".valueAsString // 0.01
"b".valueAsString // 0.02
"j".valueAsString // 0.10
"abcn".totalValueAsString // 0.20

备选方案 #2:压缩模式匹配

但是,如果您只对 String 个字符的“总值”感兴趣(过滤掉非字母字符),您可以直接将模式匹配作为过滤器应用于完整字符串,无需使用中间 .value 扩展名,例如:

/* Alternative #2 */
extension String {
    
    var totalValueAsString: String {
        let pattern = UnicodeScalar("a")..."z"
        let filteredSum = self.lowercaseString.unicodeScalars
            .filter { pattern ~= [=11=] }
            .reduce(0) { [=11=] + .value - 96 }
        return String(format: "%.2f", Float(filteredSum)/100)
    }
}

/* example usage */
"abc[n".totalValueAsString // 0.20 (ignoring the non-alphabetic "[" character)

将以上内容应用于您的特定 sum(...) 函数

现在,w.r.t。您的编辑

@IBAction func sum(sender: AnyObject) {
    strValue.text = String(format: "%.2f", "$\(strInput.text!.value.description)")
}

注意

  • 您应该避免在(假定为)UITextField strInput.text 属性 上使用强制展开运算符 (!),如果这是 `nil.
  • strInput.text 属性 是一个 String,而 String(format:) 初始值设定项期望 Float 作为它的第二个参数。

因此,您在 sum(...) 函数中寻找的内容很可能更符合

@IBAction func sum(sender: AnyObject) {
    var decText : String = ""
    if let input = strInput.text {
        decText = input.totalValueAsString
    }
    else {
        decText = "0.00"
    }
    strValue.text = "$" + decText
}

鉴于您正在使用上述两个 String 扩展选项之一。


最后,为了在 UITextFields 的一般上下文中显示货币,请参见例如以下问答: