I'm studying for job interviews for Swift positions by completing code problems. By far the most painful part of this preparation is the dismal state of data structures in Swift.
If I were programming in Java (which I really rather wouldn't), I would have easy access to...
Java's collections
Sets
- Unordered sets (
HashSet
,CopyOnWriteArraySet
,EnumSet
) - Insertion ordered sets (
LinkedHashSet
) - Naturally ordered sets (
TreeSet
,ConcurrentSkipListSet
)
Maps ("Dictionaries" in Swift)
- Unordered dictionaries (
HashMap
,WeakHashMap
,IdentityHashMap
,EnumMap
) - Insertion ordered dictionaries (
LinkedHashMap
) - Naturally ordered sets (
TreeMap
)
Ordered collections
- Arrays (
ArrayList
,LinkedList
,Vector
(a synchronized array),LinkedList
) - Queues (
ArrayDeque
,ConcurrentLinkedDeque
,PriorityQueue
,SyncrhonousQueue
, ArrayBlockingQueue,
DelayQueue,
LinkedBlockingQueue,
PriorityBLockingQueue,
linkedTransferQueue,
LinkedBlockingDequeue`)
Behold this beauty: Collection Hierarchy
and Map Simple
Amazingly, many Java programmers don't even find these sufficient! The Guava library (a ubiquitous Java library by Google) adds in all kinds of collections like multi maps (map keys to multiple values), BiMaps (which offer O(1)
look up from key to value, and from value to key), and all kinds of immutable, concurrent, lazy, etc. variants of most things above.
Meanwhile in Swift land
We have just Set
(unordered), Dictionary
(unordered), and Array
. No concurrent collections (value types solves most of the issues here, but it doesn't solve things like the classic produce-consumer, for example), no linked lists, queues, stacks, bimaps, multimaps, or sort ordered collections.
If we import the ObjC data structures available from Foundation, and have a masochistic desire to cast everywhere because of the lack of generics, we get ordered sets, counted set, and that's ... about it.
Anticipated responses
"The standard library is meant to be very minimal"
If we took that to its conclusions, then we shouldn't have Dictionary
, Set
or Array
, either. People should just use Unsafe(Mutable)?(Raw)?(Buffer)?Pointer
. All of those pointer types could be implemented in terms of UnsafeMutableRawPointer
, so there isn't even a need for any of the other variants.
Clearly that's infeasible. These are too useful to pass up. But so are ordered dictionaries, counted sets, and synchronized collections. I can't count how many times have I have had to wrap a dictionary and an array of keys for ordering (it's real fun to keep them in sync!).
"But you can just import XYZ library"
Generally yes, but not in a programming challenge, interview or quick scratch project.
Also, there's no prevailing standards, so there's no established "common currency" types for the use-cases these structures fill.
"Just write your own"
...