Search code examples
swiftdictionarysubsequence

Dictionary value returning nil in Swift


In this code, I am trying to extract week days from a string. I created a dictionary named dayDictionary to access to week days faster

dayDictionary is populated perfectly, but I can't access the element, it always returning nil

dictionary accessing code snip is

for word in components {
        //print(String (word))

        if previous == "to" {
            //print("Hi end")
            endIndex = dayDictionary[String (word)] ?? -1
            break
        }

        if word == "to" {
            //print("Hi Start")

            startIndex = dayDictionary[previous] ?? -1
            continue
        }

        if let validIndex = dayDictionary[String (word)] {
            duration += [validIndex]
            print("Valid")
        }

        previous = String (word)
    }

Here's the full code for better understanding

func findWeekDays(sentence: String, weekdays: [String]) -> [Int] {
    var dayDictionary: [String : Int] = [:]

    for index in 0..<weekdays.count {
        dayDictionary[weekdays[index]] = index
    }

    print(dayDictionary)

    sentence.lowercased()
    let components = sentence.split{ !$0.isLetter }

    var duration: [Int] = []

    var startIndex: Int = -1
    var endIndex: Int = -1
    var previous: String = ""

    for word in components {
        //print(String (word))

        if previous == "to" {
            //print("Hi end")
            endIndex = dayDictionary[String (word)] ?? -1
            break
        }

        if word == "to" {
            //print("Hi Start")

            startIndex = dayDictionary[previous] ?? -1
            continue
        }

        if let validIndex = dayDictionary[String (word)] {
            duration += [validIndex]
            print("Valid")
        }

        previous = String (word)
    }

    //print("\(startIndex), \(endIndex)")

    if startIndex != -1 && endIndex != -1 {
        if startIndex > endIndex {
            for index in startIndex...6 {
                duration += [index]
            }

            for index in 0...endIndex {
                duration += [index]
            }
        }

    }

    duration.sort()

    if duration.count == 0 {
        duration += [0, 1, 2, 3, 4, 5, 6]
    }

    return duration
}

func userInput() {
    let weekdays: [String] = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]

    let userSting: String = "Set alarm Monday to Friday"

    let dayIndex: [Int] = findWeekDays(sentence: userSting, weekdays: weekdays)

    for index in dayIndex {
        print("\(weekdays[index])")
    }
}

userInput()

Solution

  • You should use dayDictionary[word.description.lowercased()] instead of dayDictionary[String(word)]

    I tried with Playground and I added some print lines to for loop ->

    for word in components {
        print("word is: \(word)")
        print("components is: \(components)")
        print("previous is: \(previous)")
        print("dayDictionary is: \(dayDictionary)")
        print("item in dayDict is: \(dayDictionary[word.description.lowercased()])")
    
        if previous == "to" {
            print("Hi end")
            endIndex = dayDictionary[String(word)] ?? -1
            break
        }
    
        if word == "to" {
            print("Hi Start")
    
            startIndex = dayDictionary[previous] ?? -1
            continue
        }
    
        if let validIndex = dayDictionary[word.description.lowercased()] {
            duration += [validIndex]
            print("Valid")
        }
    
        previous = String(word)
        print("---------------------------------------")
    }
    

    Then the output is:

    1st iteration
    
    word is: Set
    components is: ["Set", "alarm", "Monday", "to", "Friday"]
    previous is: 
    dayDictionary is: ["tuesday": 1, "wednesday": 2, "saturday": 5, "monday": 0, "thursday": 3, "sunday": 6, "friday": 4]
    item in dayDict is: nil
    ---------------------------------------
    
    2nd iteration
    
    word is: alarm
    components is: ["Set", "alarm", "Monday", "to", "Friday"]
    previous is: Set
    dayDictionary is: ["tuesday": 1, "wednesday": 2, "saturday": 5, "monday": 0, "thursday": 3, "sunday": 6, "friday": 4]
    item in dayDict is: nil
    ---------------------------------------
    
    3rd iteration
    
    word is: Monday
    components is: ["Set", "alarm", "Monday", "to", "Friday"]
    previous is: alarm
    dayDictionary is: ["tuesday": 1, "wednesday": 2, "saturday": 5, "monday": 0, "thursday": 3, "sunday": 6, "friday": 4]
    item in dayDict is: Optional(0)
    Valid
    ---------------------------------------
    
    4th iteration
    
    word is: to
    components is: ["Set", "alarm", "Monday", "to", "Friday"]
    previous is: Monday
    dayDictionary is: ["tuesday": 1, "wednesday": 2, "saturday": 5, "monday": 0, "thursday": 3, "sunday": 6, "friday": 4]
    item in dayDict is: nil
    Hi Start
    
    5th iteration
    
    word is: Friday
    components is: ["Set", "alarm", "Monday", "to", "Friday"]
    previous is: Monday
    dayDictionary is: ["tuesday": 1, "wednesday": 2, "saturday": 5, "monday": 0, "thursday": 3, "sunday": 6, "friday": 4]
    item in dayDict is: Optional(4)
    Valid
    ---------------------------------------
    

    Please look at the third and fifth iterations. We could get the item from dayDictionary.