NEW: Subscribe to Hacking with Swift+ and accelerate your learning! >>

Moving from Python dictionaries to Swift dictionaries

Forums > Swift

I found the article about dynamiclookup, but I'm really struggling moving from Python to Swift when it comes to dictionaries. I've been posting questions over at stackoverflow, but I figured I would ask here as well.

In Python I can have a dictionary, we'll call 'calDict', and the structure looks like this:


/*
 Dictionary structure:

{
    2020: {
        "January": {
            1: {
                "day":"Wednesday",
                "event1": {
                    "description":"Colonoscopy",
                    "time":"8:00AM",
                    "duration":60,
                    "alert":true,
                    "location":"Bottoms up clinic, Southside",
                    "note":"Not looking forward to this."
                }
                "event2": {
                    "description":"EDG",
                    "time":"9:00AM",
                    "duration":45,
                    "alert":false,
                    "location":"Bottoms up clinic, Southside",
                    "note":"Hope they change tubes.",
                    "flags1: [1,5,27]
                }
            }
            2: {
                "day":"Thursday",
                "event1": {
                    "description":"Vasectomy",
                    "time":"8:00AM",
                    "duration":60,
                    "alert":true,
                    "location":"Quick snips",
                    "note":"This year sucks!"
                    "flags2: ["Urgent", "Must Do"]
                }
            }
            3: {
                "day":"Friday",
                "event1": {
                    "description":"Party up with friends",
                    "time":"9:00PM",
                    "duration":240,
                    "alert":true,
                    "location":"Marco's Pillow Bar",
                    "note":"Call ahead to reserve large pillows to sit on"
                }
            }
            4: {
                "day":"Saturday"
            }
            5: {
                "day":"Sunday"
            }
            6: {
                "day":"Monday"
            }
        }
        "February": {
            13: {
                "day":"Thursday"
            }
            14: {
                "day":"Friday",
                "event1": {
                    "description":"Call Gloria and tell her you're not feeling good.",
                    "time":"7:00AM",
                    "duration":5,
                    "alert":true,
                    "location":"",
                    "note":"Remember to sound really sick on the phone."
                }
                "event2": {
                    "description":"Boating with Billy and his lady friends from work."
                    "time":"8:00AM"
                    "duration":480
                    "alert":true
                    "location":"Tear Drop Lake"
                    "note":"Get beer, ice, and sunscreen.  And do not comment about Barbara's big nose."
                }
            }
        }
    }
}
*/

In Python one creates the dictionary by declaring as

calDict = {}

I could then create 2020

calDict[2020] = {}

Then you'd create the months:

calDict[2020]["January"] = {}
calDict[2020]["February"] = {}

Then you'd create the days:

calDict[2020]["January"][2] = {}
calDict[2020]["January"][2]["day"] = "Thursday"

If events exist for the day, they're further created:

calDict[2020]["January"][2]["event1"] = {}
calDict[2020]["January"][2]["event1"]"description"] = "Vasectomy"
calDict[2020]["January"][2]["event1"]"time"] = "8:00AM"
calDict[2020]["January"][2]["event1"]"duration"] = 60
calDict[2020]["January"][2]["event1"]"alert"] = true
calDict[2020]["January"][2]["event1"]"location"] = "Quick snips"
calDict[2020]["January"][2]["event1"]"note"] ="This year sucks!
calDict[2020]["January"][2]["event1"]"flags2"] = ["Urgent", "Must Do"]

How would I implement this in Swift? I'm using XCode 11.5 with Swift 5.2 on macOS Catalina 10.15.5.

I have tried in Swift Playground:

var calDict:[Int:[String:[Int:[String:String][String:String, String:String, String:Int, String:Bool, String:String, String:String, String:Array]]]] = [:]

calDict[2020]["January"][1]["day"] = "Wednesday"

But all this does is make Swift Playground complain a lot. I'm just not able to wrap my brain around how to do this.

Thanks for any help!

   

That seems like a terrible structure to try to use. And not very Swifty at all.

Things like this will give you trouble because you can't story heterogeneous items in an array or dictionary:

1: {
    "day":"Wednesday",
    "event1": {
        "description":"Colonoscopy",
        "time":"8:00AM",
        "duration":60,
        "alert":true,
        "location":"Bottoms up clinic, Southside",
        "note":"Not looking forward to this."
    }
    "event2": {
        "description":"EDG",
        "time":"9:00AM",
        "duration":45,
        "alert":false,
        "location":"Bottoms up clinic, Southside",
        "note":"Hope they change tubes.",
        "flags1: [1,5,27]
    }
}

You could have a dictionary keyed by an Int, but then what type are the values? day is a string, but the event1 and event2 are themselves dictionaries.

Here's a quick and dirty (very quick and very dirty) attempt to replicate it in a more Swift-like fashion.

enum CalendarMonthName: Int {
    case january = 1, february, march, april, may, june, july, august, september, october, november, december
}

typealias EventCalendar = [Int:CalendarYear]

struct CalendarYear {
    var months: [CalendarMonthName:CalendarMonth]
}

struct CalendarMonth {
    var days: [Int: CalendarDay]
}

struct CalendarDay {
    var day: String
    var events: [CalendarEvent]?
}

struct CalendarEvent {
    var description: String
    var time: String
    var duration: Int
    var alert: Bool
    var location: String
    var note: String
    var flags1: [Int]?
    var flags2: [String]?
}

var calendarOfEvents = EventCalendar()
calendarOfEvents[2020] = CalendarYear(months: [
    .january : CalendarMonth(days: [
        1: CalendarDay(day: "Wednesday", events: [
            CalendarEvent(description: "Colonoscopy", time: "8:00AM", duration: 60, alert: true, location: "Bottoms up clinic, Southside", note: "Not looking forward to this."),
            CalendarEvent(description: "EDG", time: "9:00AM", duration: 45, alert: false, location: "Bottoms up clinic, Southside", note: "Hope they change tubes.", flags1: [1,5,27])
        ])
    ])
])
print(calendarOfEvents[2020]?.months[.january]?.days[1]?.events?[0].description)

Be aware, however, that there is a lot that can go wrong here. For instance, there is no restriction on the Int used to key a CalendarMonth struct which means adding an event for January 42nd or May -3rd, as an example, is possible. Or adding events for the year 3287.

I'd really think about some other way of approaching this data rather than trying to replicate what you are doing in Python.

   

@roosterboy, thank you for the explaination. I've been told to read up on structures and I have, but I did not see a way to keep the data heterogenous by what I was reading because the examples were not very clear to me.

I use a very large dictionary to hold all my application data. It's a music type application that reads in playlists and I hve a lot of properties I keep for each playlist and other items. The dictionary in Python was extremely helpful, easy and fluid for me to use.

Swift's struct that you showed me above has lead me into a new direction, so I really appreciate your example.

I see the issue you mention about January 42nd, May -3rd and year 3287. I will think about a way to programmitcally to limit the month days to positive integers within the limits for that month as well as the year within a reasonable time frame (i.e. 50 years?).

   

I just wanted to let you know @roosterboy that I finally got my dictionary structure figured out. Thanks a million! I can now move forward with the conversion of my software.

   

Hacking with Swift is sponsored by Paw

SPONSORED Use Paw to build, test and describe web APIs. Paw has a lightning fast native macOS interface to compose requests, collaborate in real-time on API specs, and generate client code for your applications. You can import and export API definitions.

Discover Paw for Mac

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

Not logged in

Log in
 

Link copied to your pasteboard.