Skip to main content
2 of 4
deleted 12 characters in body
ielyamani
  • 889
  • 1
  • 5
  • 18

To reproduce your code in a playground, a Media struct could be defined this way:

struct Media {
    let mediaUrl: String
    let postTimeStamp: String?
    let timeStamp: String
    
    init(mediaUrl: String, timeStamp: String, postTimeStamp: String? = nil) {
        self.mediaUrl = mediaUrl
        self.timeStamp = timeStamp
        self.postTimeStamp = postTimeStamp
    }
}

Let's suppose the value of imageUrlString is this:

let imageUrlString: [String: Media] =
    ["media1": Media(mediaUrl: "URL", timeStamp: "573889179.6991431", postTimeStamp: "573889189.73954"),
     "media4": Media(mediaUrl: "URL", timeStamp: "573889185.750419"),
     "media2": Media(mediaUrl: "URL", timeStamp: "573889181.49576"),
     "media3": Media(mediaUrl: "URL", timeStamp: "573889183.89598")]

var values = [Media]()

Your code works by relying on the chance of having the last character read from the imageUrlString dictionary, equal the order of the element you want to append to the values array.

Bear in mind that a dictionary is an unordered collection. And unless mutated, the order of elements stays the same. The worst case would be when, reading elements from the dictionary, yields elements in a reversed order. In this case, you'll have to read from the dictionary n*(n+1)/2 times, in order to build your values array. In other terms, this algorithm is has O(n²) time complexity (worst case), O(n) best case, and is not the proper Counting Sort Algorithm which is O(n).


Robustness

The code in question relies on external facts that are not checked in code. For example:

  • If imageUrlString is empty, Done will never be mutated and thus the outer loop will be infinite;
  • The order of the elements in the result array relies on the last character in a string;
  • The last character in all the keys has to exist and be numerical for j to be incremented. Otherwise, you're in for another infinite loop
  • Breaking the outer loop relies on the digits at the end of the keys go from 1 to at least imageUrlString.count.

Breaking an outer loop

Instead of mutating the variable Done (which shouldn't be uppercased since it's an instance, not a class/type/struct/enum/etc), you can break from a nested loop this way:

OuterLoop: while true {
    for i in imageUrlString {
        ...
        if imageUrlString.count == j {
            break OuterLoop
        }
        ...
    }
}

Straight forward sorting

In Swift 5, Timsort is the algorithm that is going to be used by the standard library while sorting. It has better time complexity than Introsort and is more versatile and less memory greedy than O(n) sorting algorithms.

So, why not just use it to sort the entries in imageUrlString by timeStamp or a some other more reliable criteria?

let values = imageUrlString.values
    .sorted(by: { $0.timeStamp < $1.timeStamp }) 

(If you're sure that timeStamps represent real numbers, you could cast them to Double before comparing them)

ielyamani
  • 889
  • 1
  • 5
  • 18