-
Notifications
You must be signed in to change notification settings - Fork 336
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A very fast sortUsingDescriptors: #1560
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -334,7 +334,16 @@ | |
|
||
- (void)sortUsingDescriptors:(CPArray)descriptors | ||
{ | ||
[self sortUsingFunction:compareObjectsUsingDescriptors context:descriptors]; | ||
var i = [descriptors count], | ||
jsDescriptors = []; | ||
|
||
// Revert the order of the descriptors | ||
while (i--) | ||
{ | ||
var d = [descriptors objectAtIndex:i]; | ||
[jsDescriptors addObject:{ "k": [d key], "a": [d ascending], "s": [d selector]}]; | ||
} | ||
sortArrayUsingJSDescriptors(self, jsDescriptors); | ||
} | ||
|
||
/*! | ||
|
@@ -343,14 +352,46 @@ | |
@param aContext an object that will be passed to \c aFunction with comparison | ||
*/ | ||
- (void)sortUsingFunction:(Function)aFunction context:(id)aContext | ||
{ | ||
sortArrayUsingFunction(self, aFunction, aContext); | ||
} | ||
|
||
/*! | ||
Sorts the receiver array using an Objective-J method as a comparator. | ||
@param aSelector the selector for the method to call for comparison | ||
*/ | ||
- (void)sortUsingSelector:(SEL)aSelector | ||
{ | ||
sortArrayUsingFunction(self, selectorCompare, aSelector); | ||
} | ||
|
||
@end | ||
|
||
@implementation CPArray (CPMutableCopying) | ||
|
||
- (id)mutableCopy | ||
{ | ||
var r = [CPMutableArray new]; | ||
[r addObjectsFromArray:self]; | ||
return r; | ||
} | ||
|
||
@end | ||
|
||
var selectorCompare = function(object1, object2, selector) | ||
{ | ||
return [object1 performSelector:selector withObject:object2]; | ||
}; | ||
|
||
var sortArrayUsingFunction = function(array, aFunction, aContext) | ||
{ | ||
var h, | ||
i, | ||
j, | ||
k, | ||
l, | ||
m, | ||
n = [self count], | ||
n = array.length, | ||
o; | ||
|
||
var A, | ||
|
@@ -365,56 +406,30 @@ | |
l = 0; | ||
|
||
for (i = 0, j = l; j <= m; i++, j++) | ||
B[i] = self[j]; | ||
B[i] = array[j]; | ||
|
||
for (i = 0, k = l; k < j && j <= m + h; k++) | ||
{ | ||
A = self[j]; | ||
A = array[j]; | ||
o = aFunction(A, B[i], aContext); | ||
|
||
if (o >= 0) | ||
self[k] = B[i++]; | ||
array[k] = B[i++]; | ||
else | ||
{ | ||
self[k] = A; | ||
array[k] = A; | ||
j++; | ||
} | ||
} | ||
|
||
while (k < j) | ||
self[k++] = B[i++]; | ||
array[k++] = B[i++]; | ||
} | ||
} | ||
} | ||
|
||
/*! | ||
Sorts the receiver array using an Objective-J method as a comparator. | ||
@param aSelector the selector for the method to call for comparison | ||
*/ | ||
- (void)sortUsingSelector:(SEL)aSelector | ||
{ | ||
[self sortUsingFunction:selectorCompare context:aSelector]; | ||
} | ||
|
||
@end | ||
|
||
@implementation CPArray (CPMutableCopying) | ||
|
||
- (id)mutableCopy | ||
{ | ||
var r = [CPMutableArray new]; | ||
[r addObjectsFromArray:self]; | ||
return r; | ||
} | ||
|
||
@end | ||
|
||
var selectorCompare = function selectorCompare(object1, object2, selector) | ||
{ | ||
return [object1 performSelector:selector withObject:object2]; | ||
}; | ||
|
||
// sort using sort descriptors | ||
var compareObjectsUsingDescriptors= function compareObjectsUsingDescriptors(lhs, rhs, descriptors) | ||
var compareObjectsUsingDescriptors = function(lhs, rhs, descriptors) | ||
{ | ||
var result = CPOrderedSame, | ||
i = 0, | ||
|
@@ -425,3 +440,114 @@ var compareObjectsUsingDescriptors= function compareObjectsUsingDescriptors(lhs, | |
|
||
return result; | ||
}; | ||
|
||
// Observe that the sort descriptors has the reversed order by the caller | ||
var sortArrayUsingJSDescriptors = function(a, d) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know this has been merged already, but we might want to make this function more readable. All the one letter variable names are very hard to translate to a meaning and this function will be very hard to maintain for everybody that hasn't written it and even for the original author 3 months from now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree completely. Maybe the original author would be kind enough to make it more readable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i'm the one who submitted the merge-sort function and it's a port from C. I can't find the original source right now but i'll keep searching. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That was obvious. ;-) |
||
{ | ||
var h, | ||
i, | ||
j, | ||
k, | ||
l, | ||
m, | ||
n = a.length, | ||
dl = d.length - 1, | ||
o, | ||
c = {}; | ||
|
||
var A, | ||
B = [], | ||
C1, | ||
C2, | ||
cn, | ||
aUID, | ||
bUID, | ||
key, | ||
dd; | ||
|
||
if (dl < 0) | ||
return; | ||
|
||
for (h = 1; h < n; h += h) | ||
{ | ||
for (m = n - 1 - h; m >= 0; m -= h + h) | ||
{ | ||
l = m - h + 1; | ||
|
||
if (l < 0) | ||
l = 0; | ||
|
||
for (i = 0, j = l; j <= m; i++, j++) | ||
B[i] = a[j]; | ||
|
||
for (i = 0, k = l; k < j && j <= m + h; k++) | ||
{ | ||
A = a[j]; | ||
aUID = A._UID; | ||
|
||
if (!aUID) | ||
aUID = [A UID]; | ||
|
||
C1 = c[aUID]; | ||
|
||
if (!C1) | ||
{ | ||
C1 = {}; | ||
cn = dl; | ||
|
||
do | ||
{ | ||
key = d[cn].k; | ||
C1[key] = [A valueForKey:key]; | ||
} while (cn--) | ||
|
||
c[aUID] = C1; | ||
} | ||
|
||
bUID = B[i]._UID; | ||
|
||
if (!bUID) | ||
bUID = [B[i] UID]; | ||
|
||
C2 = c[bUID]; | ||
|
||
if (!C2) | ||
{ | ||
C2 = {}; | ||
cn = dl; | ||
|
||
do | ||
{ | ||
key = d[cn].k; | ||
C2[key] = [B[i] valueForKey:key]; | ||
} while (cn--) | ||
|
||
c[bUID] = C2; | ||
} | ||
|
||
cn = dl; | ||
|
||
do | ||
{ | ||
dd = d[cn]; | ||
key = dd.k; | ||
o = objj_msgSend(C1[key], dd.s, C2[key]); | ||
|
||
if (o && !dd.a) | ||
o = -o; | ||
} while (cn-- && o == CPOrderedSame) | ||
|
||
if (o >= 0) | ||
a[k] = B[i++]; | ||
else | ||
{ | ||
a[k] = A; | ||
j++; | ||
} | ||
} | ||
|
||
while (k < j) | ||
a[k++] = B[i++]; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and everywhere else, please separate all control structures (and their bracketed code blocks) from surrounding code with a blank line.