mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-09-04 09:53:41 +00:00
A very fast sortUsingDescriptors:
I needed to sort a lot of objects and was not impressed by the speed. Sharing my improvements...
This commit is contained in:
@@ -334,7 +334,15 @@
|
||||
|
||||
- (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]}];
|
||||
}
|
||||
sortArrayUsingJSDescriptors(self, jsDescriptors);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -344,46 +352,7 @@
|
||||
*/
|
||||
- (void)sortUsingFunction:(Function)aFunction context:(id)aContext
|
||||
{
|
||||
var h,
|
||||
i,
|
||||
j,
|
||||
k,
|
||||
l,
|
||||
m,
|
||||
n = [self count],
|
||||
o;
|
||||
|
||||
var A,
|
||||
B = [];
|
||||
|
||||
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] = self[j];
|
||||
|
||||
for (i = 0, k = l; k < j && j <= m + h; k++)
|
||||
{
|
||||
A = self[j];
|
||||
o = aFunction(A, B[i], aContext);
|
||||
if (o >= 0)
|
||||
self[k] = B[i++];
|
||||
else
|
||||
{
|
||||
self[k] = A;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
while (k < j)
|
||||
self[k++] = B[i++];
|
||||
}
|
||||
}
|
||||
sortArrayUsingFunction(self, aFunction, aContext);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -392,7 +361,7 @@
|
||||
*/
|
||||
- (void)sortUsingSelector:(SEL)aSelector
|
||||
{
|
||||
[self sortUsingFunction:selectorCompare context:aSelector];
|
||||
sortArrayUsingFunction(self, selectorCompare, aSelector);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -413,8 +382,52 @@ var selectorCompare = function selectorCompare(object1, object2, selector)
|
||||
return [object1 performSelector:selector withObject:object2];
|
||||
};
|
||||
|
||||
var sortArrayUsingFunction = function sortArrayUsingFunction(array, aFunction, aContext)
|
||||
{
|
||||
var h,
|
||||
i,
|
||||
j,
|
||||
k,
|
||||
l,
|
||||
m,
|
||||
n = array.length,
|
||||
o;
|
||||
|
||||
var A,
|
||||
B = [];
|
||||
|
||||
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] = array[j];
|
||||
|
||||
for (i = 0, k = l; k < j && j <= m + h; k++)
|
||||
{
|
||||
A = array[j];
|
||||
o = aFunction(A, B[i], aContext);
|
||||
if (o >= 0)
|
||||
array[k] = B[i++];
|
||||
else
|
||||
{
|
||||
array[k] = A;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
while (k < j)
|
||||
array[k++] = B[i++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort using sort descriptors
|
||||
var compareObjectsUsingDescriptors= function compareObjectsUsingDescriptors(lhs, rhs, descriptors)
|
||||
var compareObjectsUsingDescriptors = function compareObjectsUsingDescriptors(lhs, rhs, descriptors)
|
||||
{
|
||||
var result = CPOrderedSame,
|
||||
i = 0,
|
||||
@@ -425,3 +438,95 @@ var compareObjectsUsingDescriptors= function compareObjectsUsingDescriptors(lhs,
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// Observe that the sort descriptors has the reversed order by the caller
|
||||
var sortArrayUsingJSDescriptors = function sortArrayUsingJSDescriptors(a, d)
|
||||
{
|
||||
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;
|
||||
|
||||
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
|
||||
{
|
||||
key = d[cn].k;
|
||||
o = [C1[key] compare:C2[key]];
|
||||
if (o && !d[cn].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++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user