【问题标题】:Mutate swift array of strings (swift 2)突变 swift 字符串数组 (swift 2)
【发布时间】:2015-11-14 08:26:36
【问题描述】:

我有一个字符串数组。例如,这个:

var stringArray1 = ["abcdef", "bcdefg", "cdefgh"]

我想改变数组并取出每个字符串的前 3 个字符。结果是这样的:

var newStringArray1 = ["def", "efg", "fgh"]

从 Apple 的文档中,我尝试了这个:

func mutateArray(x: [String]) -> [String] {
    var newArray = [String]()
    for i in x {
        let range =  i.startIndex.advancedBy(3)
        i.removeRange(range)
        newArray.append(i)
    }
    return newArray
}

但是这一行:

i.removeRange(range)

给了我一个错误:“不能在可变值上使用变异成员:“i”是一个“let”常量。”

我怎样才能改变这样的数组?我听说 map() 函数也可以,但是在搜索 map 函数时,我收到的大部分解释来自 swift 1/1.2,它在 swift 2 中发生了变化。

谢谢

【问题讨论】:

  • 如果将i设置为var,程序会崩溃……i是数组中的索引,而不是里面的字符串!
  • oh i 不代表索引的内容,而是索引本身。这对于我为什么会收到错误是有道理的。谢谢。

标签: arrays swift swift2


【解决方案1】:

两种解决方案:

  • 使用substringFromIndex

    func mutateArray(x: [String]) -> [String] {
      var newArray = [String]()
      for i in x {
        newArray.append(i.substringFromIndex(i.startIndex.advancedBy(3)))
      }
      return newArray
    }
    
    
    let stringArray1 = ["abcdef", "bcdefg", "cdefgh"]
    let trimmedStringArray = mutateArray(stringArray1)
    
  • 使用map

    let trimmedStringArray = stringArray1.map {$0.substringFromIndex($0.startIndex.advancedBy(3))}
    

在这两种情况下,如果不能保证始终至少有 3 个字符,则应检查输入字符串的长度。

【讨论】:

    【解决方案2】:

    你可以这样使用强大的map函数:

    func mutatedArray(array: [String]) -> [String] {
        return array.map {
            $0.substringFromIndex($0.startIndex.advancedBy(3))
        }
    }
    

    测试:

    var list0 = ["abcdef", "bcdefg", "cdefgh"]
    mutatedArray(list0) // ["def", "efg", "fgh"]
    
    var list1 = ["def", "efg", "fgh"]
    mutatedArray(list1) // ["", "", ""]
    

    扩展

    您还可以将该函数编写为可用于ArraysStrings 的扩展。

    extension SequenceType where Generator.Element == String {
        func mutatedArray(removeChars: Int) -> [String] {
            return self.map {
                $0.substringFromIndex($0.startIndex.advancedBy(removeChars))
            }
        }
    }
    

    测试:

    var list1 = ["def", "efg", "fgh"]
    list1.mutatedArray(2) // ["f", "g", "h"]
    

    注意

    请注意,我将函数的名称更改为 mutatedArray,因为它返回的是一个新数组,而不是原始数组。

    【讨论】:

    • 这里有很多很酷的东西我不知道你可以用swift做!谢谢。
    • 是“Extension SequenceType where Generator.Element == String”与“Extension String : { // code here }”语法有什么不同?
    • 不同之处在于,如果您写extension String { ... },您就是在向String 添加一些内容。另一方面,使用extension SequenceType where Generator.Element == String { ... },您正在向SequenceType 协议添加功能序列的元素是String(例如Array of String,因为Array 确实符合@ 987654336@)。这是 Protocol-Oriented 语言之美的一部分,例如 Swift :-)
    【解决方案3】:

    您不能在for in 循环中修改“计数器”(在这种情况下不是真正的计数器)变量。使用普通循环并创建一个新对象。

    //standard for
    for (var j = 0; j < x.length; j++) {
        var i: String = x[i] //copy contents of object
        let range =  i.startIndex.advancedBy(3)
        i.removeRange(range)
        newArray.append(i)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-08
      • 2016-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多