【问题标题】:How to decrement a Character that contains a digit? [closed]如何减少包含数字的字符? [关闭]
【发布时间】:2016-02-18 18:34:39
【问题描述】:

c 是 Swift 中的一个字符变量,我碰巧知道它包含一个从 1 到 9 的数字。我想减少存储在 c 中的数字的值,这是我能想到的最好的:

c = Character(String(Int(String(c))! - 1))

这看起来非常令人费解。有没有更好的办法?

【问题讨论】:

  • 定义“更好”... :)
  • 我想这是审美偏好,但是从 Character 到 String 再到 Int 到 String 最后再回到 Character 似乎不可能是最好的方法。这是一段非常丑陋的代码,写完之后,“一定有更好的方法”立即浮现在脑海。好吧,如果不是“更好”(在某种程度上这总是一个意见问题),你会怎么做呢?
  • 好吧,正如你自己所说,恐怕这只是一个见仁见智的问题。如果您确定c 将永远是您所期望的,那么强制展开是合法的 - 除了外观偏好之外,我不确定接下来要改进什么......这确实是题外话。
  • 使用字符串插值使其更短,但我不会说“更好”:Character("\(Int("\(c)")! - 1)").
  • 有了这么小的数据集,您可以定义一个字典,将每个字符映射到前一个字符。

标签: swift character


【解决方案1】:

这听起来像是 UnicodeScalar 的完美用法:

let scalar = UnicodeScalar("8")
let char = Character(UnicodeScalar(scalar.value-1)) // "7"

或者,更详细地来自一个字符变量:

let c = Character("8")
let str = String(c)
if let scalar = str.unicodeScalars.first {
    let char = Character(UnicodeScalar(scalar.value-1)) // "7"
}

这很麻烦,因为我们必须将Character 转换为String,然后是UnicodeScalar,然后再转换为Character。我会继续努力寻找更好的解决方案。

我已经弄清楚为什么 UnicodeScalar 构造函数可以使用字符串字面量。

_NSSimpleObjCType 有一个私有初始化程序(符合 UnicodeScalar),它接受字符串的第一个字符并将其传递给 rawValue 构造函数。

NSObjCRuntime.swift

extension _NSSimpleObjCType {
    init?(_ v: UInt8) {
        self.init(rawValue: UnicodeScalar(v))
    }

    init?(_ v: String?) {
        if let rawValue = v?.unicodeScalars.first {
            self.init(rawValue: rawValue)
        } else {
            return nil
        }
    }
}

【讨论】:

  • 奇怪的是,字符没有关联的标量值,但字符串对于组成字符串的每个字符都有标量值。访问和修改标量值似乎对字符很有用。至少有办法做到这一点,但显然有必要先转换为字符串。
  • @JSLigon 同意!我也不知道为什么将单个字符串文字传递给UnicodeScalar 构造函数有效,但字符或字符串变量引用却不行。
  • @JSLigon 我已经编辑了我的答案,并在 NSObjCRuntime.swift 中从UnicodeScalar 的开源 Swift 实现中找到了一个额外的发现。构造函数基本上是在做我手动做的事情。
【解决方案2】:

您可以按如下方式创建扩展:

extension Character {
    var integerValue: Int {
        return Int(String(self)) ?? 0
    }
    var predecessor: Character {
        return integerValue.predecessor() < 0  ? "0" : String(integerValue.predecessor()).characters.first!
    }
}

var c: Character = "9"
c = c.predecessor  
print(c)  // "8"

【讨论】:

    猜你喜欢
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 1970-01-01
    • 2010-12-28
    • 2012-12-27
    • 2022-01-13
    相关资源
    最近更新 更多