Sorting things in swift
Regular sorting:
let eva = Human(firstName: "Eddie", lastName: "Van Halen" )
let jp = Human(firstName:"Jimmy", lastName: "Page")
let jh = Human(firstName:"Jimi", lastName: "Hendrix")
let sv = Human(firstName:"Steve", lastName: "Vai")
var guitarists = [eva, jp,jh, sv]
guitarists.sortInPlace({$0.firstName > $1.firstName})
for human in guitarists{
Swift.print("human.firstName: " + "\(human.firstName)")
}
Custom sorting with a method:
import Cocoa
//((value1: String, value2: String) -> ())?
//Equatable
func conditionSort<T>(array:[T],_ condition: (a: T, b: T)->Bool)->Array<T>{
var sortedArray:Array<T> = [];
for (var i : Int = 0; i < array.count; i++) {
let index:Int = Utils.index(array[i], sortedArray, condition);/**/
if(index > -1){
sortedArray = ArrayModifier.splice(&sortedArray,index, 1, [array[i],sortedArray[index]])
}else{
sortedArray.append(array[i]);/*add the weightedStyle to index 0 of the sortedStyles array or weigthedStyle does not have priority append weightedStyle to the end of the array */
}
}
return sortedArray;
}
private class Utils{
/**
* Returns the index of the item in @param sortedArray that meets the @param condition method "true", if there is no item in the @param sortedArray meets the condition method "true" then return -1 (-1 means no match found)
*/
class func index<T>(value:T, _ sortedArray:[T],_ condition:(a: T, b: T)->Bool)->Int{
for (var i : Int = 0; i < sortedArray.count; i++) {
if(condition(a: value,b: sortedArray[i])) {
return i
}
}
return -1;
}
}
class ArrayModifier{
class func splice<T>(inout array:[T],_ startIndex:Int,_ deleteCount:Int,_ values:Array<T> = [])->Array<T>{
var returnArray = array
returnArray.removeRange(Range<Int>(start:Int(startIndex),end:Int(startIndex + deleteCount)))
if(values.count > 0 ){returnArray.insertContentsOf(values, at: Int(startIndex))}
return returnArray
}
}
//7,3,2,4,9,15,1
var numbers = [4,2,5,1,0,-1,22,3]
func before<T:Comparable>(a: T, b: T) -> Bool {
return a < b;
}
let sortedNumbers = conditionSort(numbers, before)//-1,0,1,2,3,4,5,22
print(sortedNumbers)
class A:Comparable,CustomStringConvertible{
var someNumber:Int
var description: String { get{return String(someNumber)} }
init(_ someNumber:Int){
self.someNumber = someNumber
}
}
func < (lhs: A, rhs: A) -> Bool {
return lhs.someNumber < rhs.someNumber
}
func == (lhs: A, rhs: A) -> Bool {
return lhs.someNumber == rhs.someNumber
}
var theList = [A(2),A(6),A(-4)]
print(conditionSort(theList, <))
//try a Custom class that is comparable
Custom sorting with Comparable and Equatable:
The Comparable protocol extends the Equatable protocol -> implement both of them
In Apple’s Reference is an example from Apple (within the Comparable protocol reference) you can see how you should do it: Don’t put the operation implementations within the class, but rather on the outside/global scope. Also you only have to implement the < operator.
Correct example:
class Person : Comparable {
let name : String
init(name : String) {
self.name = name
}
}
func < (lhs: Person, rhs: Person) -> Bool {
return lhs.name < rhs.name
}
func == (lhs: Person, rhs: Person) -> Bool {
return lhs.name == rhs.name
}
let paul = Person(name: "Paul")
let otherPaul = Person(name: "Paul")
let ben = Person(name: "Ben")
paul > otherPaul // false
paul <= ben // false
paul == otherPaul // true
EXAMPLE:
var numbers = [4,2,5,1,0,-1,22,3]
func before<T:Comparable>(a: T, b: T) -> Bool {
return a < b;
}
let sortedNumbers = conditionSort(numbers, before)//-1,0,1,2,3,4,5,22
print(sortedNumbers)
NOTE: there is also: Striding over Strideable values, which are Comparable and can be advanced an arbitrary distance in O(1).