Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending Array to check if it is sorted in Swift?

Tags:

arrays

swift

I want to extend Array class so that it can know whether it is sorted (ascending) or not. I want to add a computed property called isSorted. How can I state the elements of the Array to be comparable?

My current implementation in Playground

extension Array {   var isSorted: Bool {     for i in 1..self.count {       if self[i-1] > self[i] { return false }     }     return true   } }  // The way I want to get the computed property [1, 1, 2, 3, 4, 5, 6, 7, 8].isSorted //= true [2, 1, 3, 8, 5, 6, 7, 4, 8].isSorted //= false 

The error Could not find an overload for '>' that accepts the supplied arguments

Of course, I still got an error because Swift doesn't know how to compare the elements. How can I implement this extension in Swift? Or am I doing something wrong here?

like image 388
Ikhsan Assaat Avatar asked Jul 07 '14 03:07

Ikhsan Assaat


People also ask

How do you check if an array is already sorted?

You don't need to sort your array to check if it's sorted. Loop over each consecutive pair of elements and check if the first is less than the second; if you find a pair for which this isn't true, the array is not sorted.

Is array sorted Swift?

Any Swift Sequence (which includes common data structures, like arrays, dictionaries, and sets) can be sorted using the sorted API, which takes a closure that's used to determine the sort order by comparing two elements at a time. The built-in sorted method can be called on any Sequence (so not just arrays).

How do you check elements are sorted or not?

The basic idea for the recursive approach: 1: If size of array is zero or one, return true. 2: Check last two elements of array, if they are sorted, perform a recursive call with n-1 else, return false. If all the elements will be found sorted, n will eventually fall to one, satisfying Step 1.

Which property that used to check an array has items in Swift?

Use the isEmpty property to check quickly whether an array has any elements, or use the count property to find the number of elements in the array.


2 Answers

The alternative solution to a free function is to do what Swift's built-in Array.sort and Array.sorted methods do, and require that you pass a suitable comparator to the method:

extension Array {     func isSorted(isOrderedBefore: (T, T) -> Bool) -> Bool {         for i in 1..<self.count {             if !isOrderedBefore(self[i-1], self[i]) {                 return false             }         }         return true     } }  [1, 5, 3].isSorted(<) // false [1, 5, 10].isSorted(<) // true [3.5, 2.1, -5.4].isSorted(>) // true 
like image 178
Wes Campaigne Avatar answered Oct 23 '22 12:10

Wes Campaigne


In Swift 2.0 you can now extend protocols!

extension CollectionType where Generator.Element: Comparable {      public var isSorted: Bool {          var previousIndex = startIndex         var currentIndex = startIndex.successor()          while currentIndex != endIndex {              if self[previousIndex] > self[currentIndex] {                 return false             }              previousIndex = currentIndex             currentIndex = currentIndex.successor()         }          return true     }  }  [1, 2, 3, 4].isSorted // true ["a", "b", "c", "e"].isSorted // true ["b", "a", "c", "e"].isSorted // false [/* Anything not implementing `Comparable` */].isSorted // <~~ Type-error 

Note that because we're using Indexable.Index instead of a simple Int as an index we have to use a while-loop instead, which looks a bit less pretty and clear.

like image 32
IluTov Avatar answered Oct 23 '22 11:10

IluTov