How can I capitalize all the strings inside an array directly?
Asked Answered
M

7

8

I'm learning swift. I've been trying this in Playground. I have no idea why the string is not being capitalized here. Or is there any other way to capitalize the string inside the array directly?

Here's my code.

var dogNames = ["Sean", "fido", "Sarah", "Parker", "Walt", "abby", "Yang"]

for index in 0..<dogNames.count {
    var dogName = dogNames[index].capitalizedString
    dogNames.removeAtIndex(index)
    dogNames.append(dogName)
}

When I try to display again the variable dogNames. The strings inside are not being capitalized.

Mott answered 24/2, 2015 at 7:22 Comment(1)
You can replace directly dogNames[index] = somethingelse in your for loopSherl
D
14

update: Xcode 8.2.1 • Swift 3.0.2

var dogNames = ["Sean", "fido", "Sarah", "Parker", "Walt", "abby", "Yang"]

for (index, element) in dogNames.enumerated() {
    dogNames[index] = element.capitalized
}

print(dogNames)   // "["Sean", "Fido", "Sarah", "Parker", "Walt", "Abby", "Yang"]\n"

This is a typical case for using map():

let dogNames1 = ["Sean", "fido", "Sarah", "Parker", "Walt", "abby", "Yang"].map{$0.capitalized}

A filter() sample:

let dogNamesStartingWithS = ["Sean", "fido", "Sarah", "Parker", "Walt", "abby", "Yang"].filter{$0.hasPrefix("S")}

dogNamesStartingWithS   // ["Sean", "Sarah"]

you can combine both:

let namesStartingWithS = ["sean", "fido", "sarah", "parker", "walt", "abby", "yang"].map{$0.capitalized}.filter{$0.hasPrefix("S")}

namesStartingWithS   // ["Sean", "Sarah"]

You can also use the method sort (or sorted if you don't want to mutate the original array) to sort the result alphabetically if needed:

let sortedNames = ["sean", "fido", "sarah", "parker", "walt", "abby", "yang"].map{$0.capitalized}.sorted()

sortedNames  // ["Abby", "Fido", "Parker", "Sarah", "Sean", "Walt", "Yang"]
Delaminate answered 24/2, 2015 at 7:54 Comment(12)
hmmm cool. Haven't heard/learn yet the map function. Thanks for this!Mott
it is pretty easy just think about $0 being each item of the arrayDelaminate
@LeonardoSavioDabus could you explain about map or advice some link ? thank you so much :)Enthusiastic
map will loop through your whole array applying the closure method to all items. $0 is the item at that particular index. $0.capitalizedString is the same as yourArray[index].capitalizedString from the first to the last elementDelaminate
filter is the same but it will keep the elements only if the comparison specified in the closure is metDelaminate
Can we simple compare it to a "For in loop" ?Mott
it is a single loop through all elementsDelaminate
if you want all elements lowercase just change it to $0.lowercaseString or all upper $0.uppercaseStringDelaminate
I have added a filter and a combination of bothDelaminate
Hey thanks for this. But still I find it hard to read. Don't you think so too?Mott
it takes the string and break it down to an array of characteres Array($0), then it gets the .first character of that array, converts it back to a String String(result ) and compares it with the letter s. String(result ) == "S". If the condition is met it keep the item otherwise it discards itDelaminate
Cannot assign through subscript: subscript is get-only errorSutlej
N
3

Try to use following code :

var dogNames = ["Sean", "fido", "Sarah", "Parker", "Walt", "abby", "Yang"]

for index in 0..<dogNames.count {
    var dogName = dogNames[index].capitalizedString
    dogNames[index]=dogName
}

Output :

[Sean, Fido, Sarah, Parker, Walt, Abby, Yang]

Negro answered 24/2, 2015 at 7:29 Comment(2)
Yeah it worked. I'm so lame I didn't see because of removing an item, some items are being skipped. Anyway is there also a way to check the String if it is already capitalized so that it could lessen the process?Mott
you have to check character by NSCharacterSet.uppercaseLetterCharacterSet()Negro
A
2

By removing from the middle of the array and then appending to the end, you end up skipping over some items. Here is what the array looks like at each step:

[Sean, fido, Sarah, Parker, Walt, abby, Yang]
[fido, Sarah, Parker, Walt, abby, Yang, Sean] (index=0; Sean moved to end)
[fido, Parker, Walt, abby, Yang, Sean, Sarah] (index=1; Sarah moved to end)
[fido, Parker, abby, Yang, Sean, Sarah, Walt] (index=2; Walt moved to end)
[fido, Parker, abby, Sean, Sarah, Walt, Yang]
[fido, Parker, abby, Sean, Walt, Yang, Sarah]
[fido, Parker, abby, Sean, Walt, Sarah, Yang]
[fido, Parker, abby, Sean, Walt, Sarah, Yang]

If you want to keep the array intact, it would make more sense to replace at the same index that you took it from:

dogNames[index] = dogName

But you can do this more elegantly by using Array.map to process each item independently, and not have to deal with indexes at all:

    let dogNames = ["Sean", "fido", "Sarah", "Parker", "Walt", "abby", "Yang"]
    let capitalDogNames = dogNames.map({ (dogName) -> String in
        return dogName.capitalizedString
    })
Anaplasty answered 24/2, 2015 at 7:28 Comment(2)
Oh I see. I get it! I'm so lame. What should I do instead? I just want to capitalized each string.Mott
Yeah. The map function takes a closure and applies it to each item in an array, and gives you an array of the result. It is a little picky about what type of closure it accepts. You have to specify the return value for each item: in this case String.Anaplasty
M
2

To answer my own question as well. Summarizing everything I found in the answers here. I came up with this solution. This is what I did to fix this with less process.

var dogNames = ["Sean", "fido", "Sarah", "Parker", "Walt", "abby", "Yang"]


for index in 0..<dogNames.count {

    if dogNames[index] != dogNames[index].capitalizedString {
        var dogName = dogNames[index].capitalizedString
        dogNames[index] = dogName
    }

}
Mott answered 24/2, 2015 at 7:44 Comment(1)
Glad you could figure it out.Karinakarine
K
1

Use .uppercaseString to capitalize all characters.

Karinakarine answered 24/2, 2015 at 7:29 Comment(0)
C
1

You have to perform the loop in reverse order:

for index in reverse(0..<dogNames.count)

The reason is that when you remove an element from an array, all elements after the removed one are shifted back by one position, hence having their index changed - whereas all elements before do not have any index change. By navigating in reverse order you are sure that the items still to process haven't had their index changed.

Cesar answered 24/2, 2015 at 7:29 Comment(0)
P
1

Here is the simplest way to do it in swift 3.0:

var dogNames = ["Sean", "fido", "Sarah", "Parker", "Walt", "abby", "Yang"]

dogNames = dogNames.map {$0.capitalized}
print("dogNames: \(dogNames)")
Poona answered 23/11, 2017 at 14:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.