将返回类型更改为小数?

时间:2016-04-26 19:13:27

标签: arrays swift swift-extensions

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

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)")
}

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

2 个答案:

答案 0 :(得分:2)

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

如果你想允许这种信件 - >仅对字母表中的字母进行十进制值转换,对于字符"a""z"的unicode标量使用模式匹配可能是合适的。

另请注意Character String初始值设定项如果使用包含多个石墨烯簇的String实例调用,则会导致致命的运行时错误(例如"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 ~= $0 }
            .reduce(0) { $0 + $1.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)")
}

请注意

  • 您应该避免在(假设为)! .text的{​​{1}}属性上使用强制解包运算符(UITextField),以防这是“无”
  • strInput的{​​{1}}属性为.text,而strInput初始值设定项需要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 } 的一般上下文中显示货币,请参阅例如以下Q& A:

答案 1 :(得分:1)

value的返回值除以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