Skip to content

Commit 9c77359

Browse files
committed
Array.sort could not handle duplicate/equal values, on non-Cocoa, due to how it used the platforms sort APIs. Replaced with a custom QuickSort
1 parent 897472f commit 9c77359

File tree

1 file changed

+40
-60
lines changed

1 file changed

+40
-60
lines changed

Source/Array.swift

Lines changed: 40 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ public struct Array<T>
6868
#elseif CLR | ISLAND
6969
list = List<T>(array)
7070
#elseif COCOA
71-
list = NSMutableArray(capacity: length(array));
71+
list = NSMutableArray(capacity: length(array))
7272
for i in 0 ..< length(array) {
73-
list.addObject(array[i] ?? NSNull.null as! T);
73+
list.addObject(array[i] ?? NSNull.null as! T)
7474
}
7575
#endif
7676
}
@@ -99,9 +99,9 @@ public struct Array<T>
9999
#elseif CLR | ISLAND
100100
list = List<T>(count)
101101
#elseif COCOA
102-
list = NSMutableArray(capacity: count);
102+
list = NSMutableArray(capacity: count)
103103
for i in 0 ..< count {
104-
list.addObject(value);
104+
list.addObject(value)
105105
}
106106
#endif
107107
}
@@ -546,65 +546,45 @@ public struct Array<T>
546546
return list
547547
}
548548

549-
public mutating func sort(by isOrderedBefore: (T, T) -> Bool) {
550-
makeUnique()
551-
#if JAVA
552-
java.util.Collections.sort(list, class java.util.Comparator<T> { func compare(a: T, b: T) -> Int32 {
553-
if isOrderedBefore(a,b) {
554-
return 1
555-
} else {
556-
return -1
557-
}
558-
}})
559-
#elseif CLR
560-
list.Sort({ (a: T, b: T) -> Integer in
561-
if isOrderedBefore(a,b) {
562-
return -1
563-
} else {
564-
return 1
549+
private mutating func QuickSort(_ aLeft: Integer, _ aRight: Integer, by isOrderedBefore: (T, T) -> Bool) {
550+
var aLeft = aLeft
551+
while aLeft < aRight {
552+
var L = aLeft - 1
553+
var R = aRight + 1
554+
var Pivot = self[(aLeft + aRight) / 2]
555+
556+
while true {
557+
repeat {
558+
R -= 1
559+
} while isOrderedBefore(Pivot, self[R])
560+
561+
repeat {
562+
L += 1
563+
} while isOrderedBefore(self[L], Pivot)
564+
565+
if L < R {
566+
swapAt(L, R)
567+
} else {
568+
break
569+
}
565570
}
566-
})
567-
#elseif COCOA
568-
list.sortWithOptions(0, usingComparator: { (a: id!, b: id!) -> NSComparisonResult in
569-
if isOrderedBefore(a == NSNull.null ? nil : a, b == NSNull.null ? nil : b) {
570-
return .NSOrderedDescending
571-
} else {
572-
return .NSOrderedAscending
571+
572+
if aLeft < R {
573+
QuickSort(aLeft, R, by: isOrderedBefore)
573574
}
574-
})
575-
#endif
575+
aLeft = R + 1
576+
}
577+
}
578+
579+
public mutating func sort(by isOrderedBefore: (T, T) -> Bool) {
580+
makeUnique()
581+
QuickSort(0, count-1, by: isOrderedBefore)
576582
}
577583

578584
public func sorted(by isOrderedBefore: (T, T) -> Bool) -> [T] {
579-
#if JAVA
580-
let result = list
581-
java.util.Collections.sort(result, class java.util.Comparator<T> { func compare(a: T, b: T) -> Int32 { // ToDo: check if this is the right order
582-
if isOrderedBefore(a,b) {
583-
return 1
584-
} else {
585-
return -1
586-
}
587-
}})
588-
return [T](result)
589-
#elseif CLR || ISLAND
590-
let result = list
591-
result.Sort() { (a: T, b: T) -> Integer in // ToDo: check if this is the right order
592-
if isOrderedBefore(a,b) {
593-
return -1
594-
} else {
595-
return 1
596-
}
597-
}
598-
return [T](result)
599-
#elseif COCOA
600-
return [T](list.sortedArrayWithOptions(0, usingComparator: { (a: id!, b: id!) -> NSComparisonResult in // ToDo: check if this is the right order
601-
if isOrderedBefore(a == NSNull.null ? nil : a, b == NSNull.null ? nil : b) {
602-
return .NSOrderedDescending
603-
} else {
604-
return .NSOrderedAscending
605-
}
606-
}))
607-
#endif
585+
var result = self
586+
result.sort(by: isOrderedBefore)
587+
return result
608588
}
609589

610590
public mutating func reverse() {
@@ -624,7 +604,7 @@ public struct Array<T>
624604

625605
func joined(separator: String) -> String {
626606
#if JAVA | CLR | ISLAND
627-
let result = NativeStringBuilder();
607+
let result = NativeStringBuilder()
628608
for i in 0..<count {
629609
if i != 0, let separator = separator {
630610
result.Append(separator)
@@ -633,7 +613,7 @@ public struct Array<T>
633613
}
634614
return result.ToString()!
635615
#elseif COCOA
636-
return list.componentsJoinedByString(separator);
616+
return list.componentsJoinedByString(separator)
637617
#endif
638618
}
639619

0 commit comments

Comments
 (0)