【问题标题】:How to capitalize every other letter in a string/array in Swift?如何在 Swift 中将字符串/数组中的所有其他字母大写?
【发布时间】:2019-02-28 14:21:59
【问题描述】:

我试图在 Swift 中将字符串中的每个偶数占位符大写。所以 [0],[2],[4],[6] 中的字符都变成大写了。

我有一个声明的变量:

var str = "This is a test" 

我有一个将变量分解成数组的数组:

let characters = Array(str) //Creates the array "["T", "h", "i", "s", " ", "i", "s", " ", "a", " ", "t", "e", "s", "t"]\n"

最重要的是,我正在创建一个空数组来输入新的大写/小写字母

var newCharacters = Array<Character>()

然后在 0 处声明索引

var index = 0 //declaring the index at 0

我试图弄清楚如何创建 for 循环,该循环将嗅出偶数数组项,然后将其中找到的字符大写。

我创建了一个 for 循环,它将操纵数组中的偶数占位符,我只是不知道将每个其他的字符串大写的语法:

for letter in characters {

   if index % 2 == 0 {

     }

}

我试图弄清楚:将每个其他字母(数组中的偶数)大写的语法是什么,将它们放入新数组中,然后将其转换回字符串。

最终结果应该是:

"ThIs iS TeSt"

【问题讨论】:

    标签: arrays swift string for-loop


    【解决方案1】:

    您可以依次组合enumeratedmapjoined来创建结果:

    let str = "This is a test"
    
    let result = str.enumerated()
                    .map { $0.offset % 2 == 0 ? String($0.element).uppercased() : String($0.element) }
                    .joined()
    
    print(result)
    
    ThIs iS A TeSt
    

    说明:

    1. String 可以像 Character 的数组一样被枚举。在 String 上调用 .enumerated() 会导致它生成一系列 (offset: Int, element: Character) 元组。
    2. map 接受一个序列并创建一个数组。依次为序列的每个元素调用map 之后的闭包,闭包返回的值成为新数组中的下一个元素。
    3. $0 是传递给映射的值的默认名称。在这种情况下,我们传递 (offset: Int, element: Character) 元组。 $0.offset是字符在String中的位置,$0.element是字符。
    4. 此处使用三元运算符返回从Character 创建的String(如果偏移量为偶数)或仅返回String(如果偏移量为奇数)。
    5. map 的结果是[String],然后使用joined()String 的数组重新连接成一个String

    【讨论】:

    • 哇,就是这样!太感谢了。我仍在学习 Swift 的基础知识。所以我有一些后续问题。 - 1.枚举基本上将数组分解为每个占位符? IE。 [0]、[1]、[2].. 等等..等等? - 2. 我看到使用了joined(),这是为了将数组放回原来的连接实体吗? - 3. 我必须了解 .map 是什么,但括号中的逻辑 - 似乎您在说“对于所有可被 2 整除的数组数字,我希望该字符串元素大写”对吗?谢谢!
    • 我更新了答案,解释了它是如何工作的。
    • 感谢您的解释。我想我终于明白了。再澄清几点: 1. 枚举不创建数组,而只是将字符串分解成一个序列? 2. 我现在明白 .map 会实际创建数组。基本上是说“结果”现在是新数组吗? 3.$0.offset 本质上是 [0],[1],[2] 的值,而 $0.element 是 [0],[1],[2] 中的实际字母?你的解释很有道理。 4.所以“String($0.element).uppercased()”基本上是说将新元素放入新数组但大写?
    • 1.正确的。您可以使用Array() 将序列转换为数组。 Array(str) 为您提供str 中的字符数组,Array(str.enumerated()) 为您提供元组数组。 2. map 创建一个新数组,但我们在该数组上调用.joined() 将其转换为字符串,然后再分配给result。 3.正确 4.正确
    • 非常好。非常感谢!
    【解决方案2】:

    试试这个代码

    var str = "This is a test"
    var result = [String]()
    for (index,element) in str.enumerated() {
        var val:String =  String(element).lowercased()
        if index % 2 == 0 {
            val = String(element).uppercased()
        }
        result.append(val)
    }
    
    print(result.joined())
    

    结果

    这是一个考验

    【讨论】:

      【解决方案3】:
      let str = "This is a test"
      let result = str.indices.map {
                       str.distance(from: str.startIndex, to: $0) % 2 == 0 ?
                       str[$0...$0].uppercased() :
                       str[$0...$0].lowercased() }.joined()
      print(result)   // "ThIs iS A TeSt\n"
      

      或作为 StringProtocol 上的变异方法:

      extension StringProtocol where Self: RangeReplaceableCollection {
          mutating func capitalizeEveryOther() {
              indices.forEach {
                  replaceSubrange($0...$0, with:
                      distance(from: startIndex, to: $0) % 2 == 0 ?
                      self[$0...$0].uppercased() :
                      self[$0...$0].lowercased() )
              }
          }
          var capitalizingEveryOther: Self {
              var result = self
              result.capitalizeEveryOther()
              return result
          }
      }
      

      var str5 = "This is a test"
      
      str5.capitalizeEveryOther()
      
      print(str5)     // ThIs iS A TeSt
      

      【讨论】:

        【解决方案4】:

        一种方法是使用stride

        var str = "This is a test" 
        var chars = Array(str).map { String($0) }
        for i in stride(from: 0, to: chars.count, by: 2) {
          chars[i] = chars[i].uppercased()
        }
        var hiphopcasedStr = chars.joined()
        

        请注意,当您处于 Unicode 领域时,某些字符大写转换为多字符串,因此 Character 的数组不太合适(因此转换为 String 的数组)。

        【讨论】:

        • “一些字符大写到多字符串”——例如德语"ß"变成大写的“SS”。
        • @MartinR 它曾经成为“SS”,但自 2017 年以来,大写 ß 是(可选)官方正字法的一部分:en.m.wikipedia.org/wiki/Capital_ẞ
        • @ModusTollens 嘿,看看那个。无论如何,我的 Swift 版本 4.1.2 仍然没有收到备忘录。需要更新,看看它是否改变了什么......
        • 即使是最新的 Unicode 标准在unicode.org/Public/12.0.0/ucd/CaseFolding-12.0.0d1.txt 中也将“ß”(00DF)的大写版本定义为“SS”(0073 0073)。
        • @MartinR 是的,默认大小写是映射 ß 到 SS。 ß 到 ẞ 需要定制外壳。尽管如此,大写的ẞ在未来可能会变得更加普遍。由于官方文件中经常使用大写字母,因此应该使识别更加安全。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-10
        • 2018-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多