Reputation: 27
How do I make vowels in a String uppercase in Swift?
I tried this:
func makeVowelsUpperCase(sentence:String)-> String {
var result = String()
var vowels = "aeiou"
for i in vowels{
if sentence.contains(i){
result = sentence(i.uppercased())
}
}
return result }
makeVowelsUpperCase(word: "this is my house")
Upvotes: 1
Views: 131
Reputation: 4744
You can do it with simple code like below :
var word : String = "this is my house "
var vowels = "aeiou"
let result = word.map { vowels.contains($0) ? String($0).uppercased() : String($0) }
.joined()
print(result)
OUTPUT :
thIs Is my hOUsE
In a function :
func uppercaseVowels(_ input: String) -> String {
let result = input.map { vowels.contains($0) ? String($0).uppercased() : String($0) }
.joined()
return result
}
print(uppercaseVowels(word))
Upvotes: 0
Reputation: 63271
There's a few issues going on:
for i in vowels
your for
loop is iterating over the vowels. Within each loop body, you choose whether to keep your vowel or not depending on whether it's in the sentence or not.
The result of this is that your result string could only ever be something like "AEIOU"
, "AIU"
, etc. (i.e., it will only be a string of length 0-5, only containing some subset of those vowels)
sentence(i.uppercased())
This part just doesn't make sense. sentence
is a String
, but by using parenthesis on it, it looks like you're tryign to call it, as if it were a function (but it's not). Hence the error: "error: incorrect argument label in call (have 'word:', expected 'sentence:')"
You're reassigning result
in the loop body, which means your result
could only ever contain one character. Instead, you should make one intermediate value once, and append onto it from there.
The way you're trying to call makeVowelsUpperCase
(with an argument label of word:
) doesn't match the way it's declared (with an argument label of sentence:
).
I think this is what you had in mind:
func makeVowelsUpperCase(sentence: String) -> String {
var result = String()
let vowels = "aeiou"
for char in sentence {
if vowels.contains(char) {
result.append(char.uppercased())
} else {
result.append(char)
}
}
return result
}
makeVowelsUpperCase(sentence: "this is my house")
There's a few other issues I'd point out:
vowels
is declared mutable (var
instead of let
). Why would the set of vowels be mutable? They should always just be "aeiou"
(for English, at least).
The loop variable is called i
, which is conventional for a loop variable that's an index of some array, but in this case, it's a Character
.
The keyword label, sentence
is a little misleading. There's no real requirement that the input be a sentence. It could be a word, or a paragraph, and everything would still work as normal.
This for
loops is just implementing a mapping operation, where an input sequence (the characters of the input) is mapped into the output sequence (the potentially uppercased characters of the output) using some transformation (uppercase if vowel). This is precisely what Array.map
is for.
There's just one catch here. As it turns out, in some languages, the uppercased version of one character might actually be multiple characters. To account for this, Character.uppercased()
doesn't actually return a Character
, it returns a String
.
To cope with this, we need to use flatMap
instead of map
, which will have the effect of joining these strings returned as a result of each character-upper-casing operation.
Here's how I might right this:
func uppercaseVowels(_ input: String) -> String {
let vowels = "aeiou"
let newChars = input.flatMap { char in
vowels.contains(char) ? char.uppercased() : String(char)
}
return String(newChars)
}
print(uppercaseVowels("this is my house"))
Upvotes: 2
Reputation: 100503
You can try
func makeVowelsUpperCase(_ sentence:String)-> String {
var result = sentence
let vowels = "aeiou"
vowels.forEach {
result = result.replacingOccurrences(of: "\($0)", with: "\($0)".uppercased())
}
return result
}
Call
let str = makeVowelsUpperCase("this is my house")
print(str) // thIs Is my hOUsE
Upvotes: 1