swiftdictionarycalendardatecomponents

Populate the dictionary [DateComponents: EventType], How to add dates to a date dictionary


I would like to get this result:

var eventDate: [DateComponents: EventType] = [
        DateComponents(calendar: Calendar(identifier: .gregorian), year: 2024, month: 7, day: 04): .busy,
        DateComponents(calendar: Calendar(identifier: .gregorian), year: 2024, month: 8, day: 07): .busy,
        DateComponents(calendar: Calendar(identifier: .gregorian), year: 2024, month: 10, day: 16): .busy,
        DateComponents(calendar: Calendar(identifier: .gregorian), year: 2024, month: 12, day: 17): .busy,
        DateComponents(calendar: Calendar(identifier: .gregorian), year: 2025, month: 4, day: 18): .busy,
        DateComponents(calendar: Calendar(identifier: .gregorian), year: 2026, month: 9, day: 26): .busy
    ]

I'm trying this way but I'm not getting what I want. I don't get the list you see at the beginning.

func dateTimestampDividedInt(date: TimeInterval) -> (year: Int, month: Int, day: Int) {
            let calendar = Calendar.current
            let date = Date(timeIntervalSince1970: date)
            
            let day = calendar.component(.day, from: date)
            let month = calendar.component(.month, from: date)
            let year = calendar.component(.year, from: date)
            
            return (year, month, day)
        }
for employee in eventArrayIcon {
           
            let timeIntervalDateEndDivided = employee.dateEnd?.dateTimestampDividedInt(date: employee.dateEnd ?? 0.0)

                    let yearInt = timeIntervalDateEndDivided?.year
                    let monthInt = timeIntervalDateEndDivided?.month
                    let dayInt = timeIntervalDateEndDivided?.day
            
            eventDate = [
                DateComponents(calendar: Calendar(identifier: .gregorian), year: yearInt, month: monthInt, day: dayInt): .busy
            ]
            
        }

Solution

  • Let's simplify and focus on how works the Dictionary as all the DateComponents make things noisy. You can stop what you're doing, open a Playground and test to ensure your understanding of Dictionary is up to date and correct.

    What you're currently doing: Setting the whole value of myDic1 each time ie: Forget about your previous values, now you're just ["Key\(i)": "Value \(i)"] So its output will be the last override ie myDic1 = ["Key\(4)": "Value \(4)"]

    var myDic1: [String: Any] = [:]
    for i in 0...4 {
        myDic1 = ["Key\(i)": "Value \(i)"]
        print("Partial1: \(myDic1)")
    }
    print("Final1: \(myDic1)")
    

    What you want is to set the value for each new key:

    var myDic2: [String: Any] = [:]
    for i in 0...4 {
        myDic2["Key\(i)"] = "Value \(i)"
        print("Partial1: \(myDic2)")
    }
    print("Final2: \(myDic2)")
    

    But for Dictionaries, key are unique. Meaning that if you do:

    myDict[key] = Value0
    myDict[key] = Value1
    

    Then, myDict[key] will be Value1 (ie, the last one set for key.

    var myDic3: [String: Any] = [:]
    for i in 0...4 {
        myDic3["Key\(i)"] = "Value \(i)"
        print("Partial3: \(myDic3)")
    }
    for i in 0...4 {
        myDic3["Key\(i)"] = "New Value \(i)"
        print("Partial3: \(myDic3)")
    }
    print("Final3: \(myDic3)")
    

    So in your case, if the key DateComponents(calendar: Calendar(identifier: .gregorian), year: yearInt, month: monthInt, day: dayInt) is the same for different employee, you'll get only the last value set. So you need to change your model. I don't know what you want to do with your model, but var eventDate: [DateComponents: [EventType]] could be a solution, meaning that you can have multiple EventType for a same DateComponents, etc.

    So you need to debug and print print("Partial1: \(myDic1)") equivalent in your code inside the loop.