【问题标题】:Swift 3/4 dash to camel case (Snake to camelCase)Swift 3/4 dash to camel case (Snake to camelCase)
【发布时间】:2018-02-18 07:34:14
【问题描述】:

我正在尝试对骆驼案例执行简单的破折号: “this-is-my-id”将在 swift 3(或 4)中变为“thisIsMyId”。

无论我做什么,我都找不到足够优雅的方式来做到这一点..: 以下不起作用:

str.split(separator: "-").enumerated().map { (index, element) in
    return index > 0 ? element.capitalized : element
}.reduce("", +)

它为所有的东西哭泣。我确信有一个足够简单的方法......有人吗?

【问题讨论】:

    标签: swift swift3


    【解决方案1】:

    您的代码几乎是正确的。以下是我发现的最易读的实现:

    let str: String = "this-is-my-id"
    
    let result = str
        .split(separator: "-")  // split to components
        .map { String($0) }   // convert subsequences to String
        .enumerated()  // get indices
        .map { $0.offset > 0 ? $0.element.capitalized : $0.element.lowercased() } // added lowercasing
        .joined() // join to one string
    
    print(result)
    

    【讨论】:

    • @Cristik 好吧,我可以在.split 之后使用.lazy 做同样的事情。
    • @Cristik 无论如何你都必须这样做。我们必须衡量性能才能真正得到任何有意义的答案。但是,我认为这是过度优化。
    【解决方案2】:

    使用 Swift 4.1 更好地实现 @sulthan 的回答。

    extension String {
        func camelCased(with separator: Character) -> String {
            return self.lowercased()
                .split(separator: separator)
                .enumerated()
                .map { $0.offset > 0 ? $0.element.capitalized : $0.element.lowercased() }
                .joined()
        }
    }
    

    【讨论】:

    • 第二个lowercased()(在$0.element.lowercased()中)在技术上是不必要的,因为你已经在第一步中lowercased()了整个字符串,但是如果你不第二次调用它,您必须改用String($0.element)。第二个lowercased() 的美妙之处在于它平衡了它之前的capitalized
    【解决方案3】:

    您可以做的是根据破折号“-”(创建一个字符串数组)溢出您的字符串,并将其元素与所需的情况结合起来:

    let myString = "this-is-my-id"
    let newString = myString.split(separator: "-").reduce("", { $0 + $1.capitalized })
    
    print(newString) // "ThisIsMyId"
    

    【讨论】:

    • 第一个字母应该是小写的。另外,比起reduce("", +),更喜欢joined()
    • @Sulthan 不管“第一个字母应该是小写字母”,你能说说为什么joined 更可取吗?
    • 因为它适用于所有元素(字符串数组)的知识,因此它可以具有更好的性能。当然,代码可读性也有所提升。
    • @Sulthan 如果我没看错,是否与FlattenBidirectionalCollection 不创建新存储(总是懒惰)有关?
    • 不,这只是内部逻辑。 joined 对最终数组进行操作,因此它知道必要的大小。 reduce 一次操作一个元素。如果有可能更好性能的特定函数,则没有理由使用泛型函数。
    【解决方案4】:

    如果您通过创建新字符串来解构String.Subsequence 元素,您的语法就可以工作:

    str.split(separator: "-").enumerated().map { (index, element) in
         return index > 0 ? String(element).capitalized : String(element)
    }.joined() // better than `reduce`
    

    【讨论】:

      【解决方案5】:

      所有这些答案的组合将导致以下最短的方式(我认为 - 只有 2 次交互):

      let str: String = "this-is-my-id"
      
      let result = str.split(separator: "-").reduce("") {(acc, name) in
          "\(acc)\(acc.count > 0 ? String(name.capitalized) : String(name))"
      }
      

      谢谢大家!

      【讨论】:

      • 您可能想查看this question 了解为什么使用joined 而不是reduce
      【解决方案6】:

      您可以遍历字符(String 是字符的集合),同时拿着一个标志来指示字符是否在破折号之后,以便将其大写:

      let dashCase = "this-is-my-id"
      let camelCase = dashCase.reduce(into: ("", false)) {
          // mark the dash
          guard $1 != "-" else { $0.1 = true; return }
          $0.0 += $0.1 ? String($1).uppercased() : String($1)
          // reset the flag so we don't capitalize the next ones
          $0.1 = false
      }.0
      print(camelCase)  // thisIsMyId
      

      【讨论】:

      猜你喜欢
      • 2023-02-26
      • 2012-05-17
      • 1970-01-01
      • 2013-10-03
      • 2016-07-29
      • 2021-10-21
      • 2011-05-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多