Choosing The Right Data Structure In Swift

Posted By : Anmol Aggarwal | 12-Aug-2020

Choosing which data structure to be used for a given data collection can be trickier than it appears. Since every sort of data structure is optimized for a specific number of use cases, finding the correct counterpart for each set of data might have a significant impact on how effective our code winds up to be. The Swift standard library ships with three primary data structures, namely:

  • Array
  • Dictionary
  • Set

Each of the above given data structures have different set of optimization, pros and cons. Let’s us learn about some of those characteristics, and sometimes there might be a need to venture outside the domain of the standard library to find the right data structure as per our needs.

 

Array's Linearity

The array is one of the most regularly used data structures in Swift, and for valid reasons. It keeps its elements in arrangement, easy iterations, and it can store any sort of value — from structs, to class, to different collections.  For instance, here we're using an array to store a collection of shapes that are put on a sheet inside a drawing application. At that point, when requested to deliver our sheet into a picture, we essentially repeat through our exhibit so as to draw every component utilizing a DrawingContext — like this:

 

struct Sheet {
    var shapes: [Shape]

    func render() -> Image {
        let context = DrawingContext()
        shapes.forEach(context.draw)
        return context.makeImage()
    }
}

 

With regards to linearly drawing the all of our shapes, as we do above, using an array is an ideal fit. In addition to the fact that arrays store their components in an exceptionally effective way, they likewise have order in which iteration takes place, which gives us order of the drawing without accomplishing any additional work. 

Be that as it may, much the same as every other data structures, arrays likewise have drawbacks. For our situation, we'll begin experiencing one such drawback when we need to begin removing shapes from our sheet. Since elements of array are stored by index, we will consistently need to look into which position that a given shape is related with before we can remove it:

 

extension Sheet {
    mutating func remove(_ shape: Shape) {
        guard let index = shapes.firstIndex(of: shape) else {
            return
        }

        shapes.remove(at: index)
    }
}

From the outset the above code probably won't appear that problematic, yet it's probably going to turn into a performance bottleneck for any sheet that contains a large number of shapes — since firstIndex is direct (O(n)) as far as time complexity is concerned. 

 

While we could work around that impediment wherever we're using our Sheet type — for instance by continually referring to shapes by index, rather than by value or ID — doing so would make our code both more complex and more fragile, since we'd generally need to ensure that our indexes won't become stale at whatever point the sheet we're working with is changed.

 

Speed of Sets

Rather, how about we check whether we can optimize Sheet itself by changing its data structure. Considering the above issue, one of our underlying thoughts may be to use a Set rather than an Array. One of the biggest advantage of that sets have over array is that the both insertions and deletions can generally be done in (O(1)) time complexity, since elements are stored using hash values, instead of by indexes. Updating Sheet to use a set rather would look as shown below:

 

struct Sheet {
    var shapes: Set<Shape>

    func render() -> Image {
        let context = DrawingContext()
        shapes.forEach(context.draw)
        return context.makeImage()
    }

    mutating func remove(_ shape: Shape) {
        shapes.remove(shape)
    }
}

 

Indexing Indexes

How about we continue testing. Next, how about we check whether we can advance Sheet by presenting it as a Dictionary that lets us look into any shape's list dependent on its ID. We'll begin by making our array of shapes private to have the option to take responsibility for how components are added — using a new method— and each time another shape is included we likewise add its index to our Dictionary:

 

struct Sheet {
    private var shapes = [Shape]()
    private var indexes = [Shape.ID : Int]()

    func render() -> Image {
        let context = DrawingContext()
        shapes.forEach(context.draw)
        return context.makeImage()
    }

    mutating func add(_ shape: Shape) {
        let index = shapes.count
        indexes[shape.id] = index
        shapes.append(shape)
    }
}

 

Since we always know what the index that a given shape is located at, we can rapidly perform removals in steady time, much the same as when we were utilizing a set: 

 

extension Sheet {
    mutating func remove(_ shape: Shape) {
        guard let index = indexes[shape.id] else {
            return
        }

        shapes.remove(at: index)
        indexes[shape.id] = nil
    }
}

 

Our last implementation has some advantages however. Using a blend of two data structures can be a great idea in cases like this — since we're regularly ready to utilize the qualities of one data structure to make up for different's shortcomings, and the other way around.

 

 Conclusion

Despite the fact that data structures are fundamental to the point that they can be found in a wide range of programming languages, choosing which one to use in some in any case require a considerable measure of reasoning, testing and experimentation — particularly on the off chance that we need our code to stay proficient as it's used with a developing collection of data. 

 

All things considered, the correct data structure for some case may change after some time as our requirements which evolve over time, and at times utilizing a blend of multiple data structures — as opposed to only one — may be the best approach to accomplish the performance qualities that we need. Like with such huge numbers of different things, growing our speculation past Swift is now and again what's required so as to pick the correct data structure within every situation.

 

We are a full-scale Mobile App development company that specializes in building scalable web and mobile applications for multiple platforms. Our development team uses advanced frameworks, tools, SDKs and agile methodologies to develop feature-rich business applications with custom features. Our end-to-end mobile application development services render support for both Android and iOS platforms. We have successfully completed several full-fledged Android and iOS application development projects for startups, SMEs, and large-scale enterprises. For project-related queries, drop us a line at [email protected].

 

#MobileAppDevelopmentCompany #MobileApplicationDevelopmentServices #iOSApplicationDevelopment

About Author

Author Image
Anmol Aggarwal

Anmol is in mobile team, She is hard working developer and dedicated towards her work.

Request for Proposal

Name is required

Comment is required

Sending message..