简体   繁体   中英

Mutate swift array of strings (swift 2)

I have an array of Strings. For example, this:

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

I want to mutate the array and take out the first 3 characters of each string. The result would be this:

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

Taking from Apple's Documentation, I tried this:

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
}

but this line:

i.removeRange(range)

gave me an error: "Cannot use mutating member on mutable value: "i" is a "let" constant."

how can I change the array like this? I have heard it is possible with the map() function as well, but when searching about the map function, most of the explanations I received were from swift 1/1.2, and it changed in swift 2.

thanks

Two solutions:

  • using 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) 
  • using map

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

In both cases you should check for the length of the input string if it's not guaranteed that there are always at least 3 characters.

You can use the powerful map function this way:

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

Tests:

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

var list1 = ["def", "efg", "fgh"]
mutatedArray(list1) // ["", "", ""]

Extension

You can also write the function as an extension available for Arrays of Strings .

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

Test:

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

Note

Please note I changed the name of the function to mutatedArray since it is returning a new array and it's not changing the original one.

You can't modify the "counter" (not really a counter in this case) variable in a for in loop. Use a normal loop and create a new object.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM