2

I'm struggling with my app, which handles bus routes. I get, at a every single bus stop, every future departure of the busses leaving from there, the departure includes direction and time of departure. I want to be able to get all the times a bus leaves in a given direction, I've done it so far by creating a nested dictionary, however, I was wondering if you can do it smarter? This is what I got so far

var dict = [String: [String : [String]]]()

So it would be something like:

var dict = ["Busname": ["Direction" : ["time1", "time2", "time3"]]]()

Is there a smarter way? Or is this the way to go? I want to get a list of times of departures of the given bus with the given direction.

Recusiwe
  • 1,594
  • 4
  • 31
  • 54

1 Answers1

1

You could use structs instead of dictionaries.

Quick example, let's make a Bus object:

struct Bus {
    var name: String
    var direction: String
    var times: [NSDate]
}

It holds the values for each bus: name of the bus, its direction, and an array of dates for the bus times.

Of course it's just an example, you have to adapt to your use case.

You create your busses:

let bus1 = Bus(name: "Busey MacBusface", direction: "Somewhere", times:  [...some dates...])
let bus2 = Bus(name: "Gary Bussey", direction: "Nowhere", times:  [...some dates...])

You can have them in collections:

let todayBusses = [bus1, bus2]

Easy to filter:

let allDirections = todayBusses.map { $0.direction }
let allTimes = todayBusses.map { $0.times }
let someBusses = todayBusses.filter { $0.times.contains({ (date) in
    // compare 'date' with other date(s)
}) }
let notNowhere = todayBusses.filter { $0.direction != "Nowhere" }

Etc.

Again, this is just a quick example, but I think it can give you ideas.

"the times for a specific name of a bus" would be something like:

let times = todayBusses.filter { $0.name == "theBusName" }.map { $0.times }
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
  • How would you get the times for a specific name of a bus? I would need to search for the bus and then print out the items in the array? – Recusiwe Jun 18 '16 at 18:08
  • I've updated my answer with an example. Note that I'm using map and filter for my examples but if you're not familiar with this you can also use loops as usual of course. – Eric Aya Jun 18 '16 at 18:10
  • At the moment I have a class with the stops and a class with the derpartures, which is contained in the stop class in an array. So you would just make another class/struct and loop through all the departures to make sure they get added to the correct bus-object? The things is, that the same bus will be repeated numerous of times in the JSON, since it has several departures a day. So I guess I'll have to loop through my list of busses and check if the one I'm at is already in there, and If not I'll create an object and add it, otherwise I'll just add the time to the list of the current object? – Recusiwe Jun 18 '16 at 18:15
  • It's up to you to decide how you structure your classes (or structs) but I would strongly recommend not using nested dictionaries. It's very cumbersome and not type safe - on the other hand, well-structured objects and convenient wrappers around them (a BusManager can have an array of Bus objects and methods to sort them, for example) are life savers when using and filtering collections like you're doing. IMO, of course - there's other patterns, but this is a rather usual one. – Eric Aya Jun 18 '16 at 18:19
  • I see. Just another question, when I go through the list to check if an element is already there I use `list.contains(item)` however, when the element is contained I want to add the item time to the current items array, how is this possible? – Recusiwe Jun 18 '16 at 18:41
  • You can use `indexOf`. This could help: http://stackoverflow.com/a/32953118/2227743 Once you get the index, you can subscript the array to get the object, then you add it where you want. – Eric Aya Jun 18 '16 at 18:43
  • Thanks! I want to compare the elements from the two different list on their name, how can I do this? I got two different object, a Departure-object and a BusDeparture-Object. So I guess I need to specify, in my contains, what they should compare? – Recusiwe Jun 18 '16 at 18:50
  • You're welcome. The example I just linked does that exactly (you just adapt to your own types). // You can also just compare their properties directly in various methods instead of making everything Equatable - your choice, depends what you need/prefer. – Eric Aya Jun 18 '16 at 18:52
  • And I would just compare their names instead of the hashvalues since the objects are different, right? – Recusiwe Jun 18 '16 at 18:56
  • Yes, exactly like in the first part of the linked example. The second part is more about comparing objects by a computed uniqueness instead of just a property like the name. – Eric Aya Jun 18 '16 at 18:57
  • And where would I put that function when I'm comparing two different objects? – Recusiwe Jun 18 '16 at 18:58
  • I can't decide for you my friend. It can be in the Bus struct itself, or in a Manager class, you decide how you architecture all this, you decide what makes more sense. It depends on so many things. Open a Playground and go experiment now, this question is resolved. ;) If you have new questions, don't hesitate but make a new post, it's better. You can point to this one in the new one if necessary. – Eric Aya Jun 18 '16 at 19:02
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/115018/discussion-between-recusiwe-and-eric-d). – Recusiwe Jun 18 '16 at 19:05