0

So I am trying to take thee first index of a string (fullName) and test it to see if it matches all vowels lower and uppercased... for some reason when I use the .startIndex I test one letter at a time with a If statement.

Ia there a way to test all vowels at once ()I tried || in between each and it gave me the error "cannot convert string to Bool". Appreciate any help.

func lyricsForName(lyricsTemplate: String, fullName: String) -> String {

    let shortName = shortNameFromName(name: fullName)
    let index = fullName[fullName.startIndex]
    if index== ("a","A"){

        let lyrics = lyricsTemplate
            .replacingOccurrences(of:"<FULL_NAME>", with: fullName)
            .replacingOccurrences (of:"<SHORT_NAME>", with: fullName )

        return lyrics
    }else{
        let lyrics = lyricsTemplate
            .replacingOccurrences(of:"<FULL_NAME>", with: fullName)
            .replacingOccurrences (of:"<SHORT_NAME>", with: shortName )

        return lyrics
2
  • 1
    index it is not a good name for a character. if String(fullName.characters.prefix(1)).uppercased() == "A" Commented Jan 31, 2017 at 3:00
  • mhhh interesting question. but why you need it? Commented Jan 31, 2017 at 4:11

3 Answers 3

1

You can do it as previously answered, but this is a more Swifty way using the available APIs:

extension String {
    var firstThreeLettersAreVowels: Bool {
        guard characters.count >= 3 else {
            return false
        }

        let firstThreeLetters = substring(to: index(startIndex, offsetBy: 3))
        let isAllVowels = CharacterSet(charactersIn: firstThreeLetters).isSubset(of: CharacterSet.vowels)
        return isAllVowels
    }

    var isLower: Bool {
        return CharacterSet(charactersIn: self).isSubset(of: CharacterSet.lowercaseLetters)
    }

    var isUpper: Bool {
        return CharacterSet(charactersIn: self).isDisjoint(with: CharacterSet.lowercaseLetters)
    }
}

extension CharacterSet {
    static var vowels: CharacterSet {
        return CharacterSet(charactersIn: "AEIOUYaeiouy")
    }
}

Or the one liner (without length check) is

extension String {
    var firstThreeLettersAreVowels: Bool {
        return CharacterSet(charactersIn: substring(to: index(startIndex, offsetBy: 3)))
                    .isSubset(of: CharacterSet(charactersIn: "AEIOUYaeiouy"))
    }
}

This allows you rely on existing APIs rather than trying to do the work yourself, and it should be pretty fast.

Sign up to request clarification or add additional context in comments.

11 Comments

it think it was a typo thee means the
anyway this guard is wrong guard characters.count >= 3 else
it should be check it there are less then 3 letters guard characters.count < 3 else
oh sorry - i mixed it up - yes you are right - i forget it should be true and otherwise it do the else and return false if chars.count one of 0,1,2
|
1

Here is one way to do it. You can use an array of vowels and then test if the array contains the first character:

let fullName = "Albert"

let vowels = "aeiouAEIOU".characters    

if let first = fullName.characters.first, vowels.contains(first) {
    print("\(fullName) starts with a vowel")
}

Albert starts with a vowel

Note: Using fullName.characters.first is safer than fullName[fullName.startIndex] because the latter will crash for an empty String.

1 Comment

and with fullName.characters.first.uppercased you can half the vowels array
0

all kudos please to PEEJWEEJ answer

the characterset was his idea :)

i made it only more general

import Foundation

extension String {
    func isFirstLetters(count: Int, of characterSet: CharacterSet) -> Bool {

        guard characters.count >= count else {
            return false
        }

        let firstLetters = substring(to: index(startIndex, offsetBy: count))
        let isInSubset = CharacterSet(charactersIn: firstLetters).isSubset(of: characterSet

        )
        return isInSubset
    }
}

extension CharacterSet {
    static var vowels: CharacterSet {
        return CharacterSet(charactersIn: "AEIOUYaeiouy")
    }
}

some Test cases:

"abcDEf".isFirstLetters(count: 3, of: .vowels) // false
"aioDEf".isFirstLetters(count: 3, of: .vowels) // true

"abcDEf".isFirstLetters(count: 1, of: .vowels) // true
"bbcDEf".isFirstLetters(count: 1, of: .vowels) // false
"ibcDEf".isFirstLetters(count: 1, of: .vowels) // true

"ABcdef".isFirstLetters(count: 3, of: .uppercaseLetters) // false
"ABDdef".isFirstLetters(count: 3, of: .uppercaseLetters) // true

"abBABcdef".isFirstLetters(count: 3, of: .lowercaseLetters) // false
"abbABDdef".isFirstLetters(count: 3, of: .lowercaseLetters) // true


"ABD".isFirstLetters(count: 3, of: CharacterSet(charactersIn: "A"..."C")) // false
"ABD".isFirstLetters(count: 3, of: CharacterSet(charactersIn: "A"..."D")) // true

debug info:

extension CharacterSet {
    var characters: [Character] {
        var result: [Character] = []
        for plane: UInt8 in 0...16 where self.hasMember(inPlane: plane) {
            for unicode in UInt32(plane) << 16 ..< UInt32(plane + 1) << 16 {
                if let uniChar = UnicodeScalar(unicode), self.contains(uniChar) {
                    result.append(Character(uniChar))
                }
            }
        }
        return result
    }
}



print(CharacterSet.uppercaseLetters.description)
//<Foundation._SwiftNSCharacterSet: 0x6000000271a0>

print(String(CharacterSet.vowels.characters))
//AEIOUYaeiouy

print(CharacterSet.vowels.characters)
// ["A", "E", "I", "O", "U", "Y", "a", "e", "i", "o", "u", "y"]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.