Added -indexOfObjectPassingTest: and related methods

This commit is contained in:
Aparajita Fishman authored and Ross Boucher committed 2010-07-28 15:57:47 -07:00
1 parent b4dbe422ff
commit cb7f60aba8
2 files changed
+145

No files matched your search

+95
View File
@@ -26,6 +26,9 @@
@import "CPRange.j"
@import "CPSortDescriptor.j"
CPEnumerationNormal = 0;
CPEnumerationConcurrent = 1 << 0;
CPEnumerationReverse = 1 << 1;
/* @ignore */
@implementation _CPArrayEnumerator : CPEnumerator
@@ -397,6 +400,98 @@
return CPNotFound;
}
/*!
Returns the index of the first object in the receiver that passes a test in a given Javascript function.
@param predicate The function to apply to elements of the array. The function receives two arguments:
object The element in the array.
index The index of the element in the array.
The predicate function should either return a Boolean value that indicates whether the object passed the test,
or nil to stop the search, which will return CPNotFound to the sender.
@return The index of the first matching object, or \c CPNotFound if there is no matching object.
*/
- (unsigned)indexOfObjectPassingTest:(Function)predicate
{
return [self indexOfObjectWithOptions:CPEnumerationNormal passingTest:predicate context:nil];
}
/*!
Returns the index of the first object in the receiver that passes a test in a given Javascript function.
@param predicate The function to apply to elements of the array. The function receives two arguments:
object The element in the array.
index The index of the element in the array.
context The object passed to the receiver in the aContext parameter.
The predicate function should either return a Boolean value that indicates whether the object passed the test,
or nil to stop the search, which will return CPNotFound to the sender.
@param context An object that contains context information you want passed to the predicate function.
@return The index of the first matching object, or \c CPNotFound if there is no matching object.
*/
- (unsigned)indexOfObjectPassingTest:(Function)predicate context:(id)aContext
{
return [self indexOfObjectWithOptions:CPEnumerationNormal passingTest:predicate context:aContext];
}
/*!
Returns the index of the first object in the receiver that passes a test in a given Javascript function.
@param opts Specifies the direction in which the array is searched. Pass CPEnumerationNormal to search forwards
or CPEnumerationReverse to search in reverse.
@param predicate The function to apply to elements of the array. The function receives two arguments:
object The element in the array.
index The index of the element in the array.
The predicate function should either return a Boolean value that indicates whether the object passed the test,
or nil to stop the search, which will return CPNotFound to the sender.
@return The index of the first matching object, or \c CPNotFound if there is no matching object.
*/
- (unsigned)indexOfObjectWithOptions:(CPEnumerationOptions)opts passingTest:(Function)predicate
{
return [self indexOfObjectWithOptions:opts passingTest:predicate context:nil];
}
/*!
Returns the index of the first object in the receiver that passes a test in a given Javascript function.
@param opts Specifies the direction in which the array is searched. Pass CPEnumerationNormal to search forwards
or CPEnumerationReverse to search in reverse.
@param predicate The function to apply to elements of the array. The function receives two arguments:
object The element in the array.
index The index of the element in the array.
context The object passed to the receiver in the aContext parameter.
The predicate function should either return a Boolean value that indicates whether the object passed the test,
or nil to stop the search, which will return CPNotFound to the sender.
@param context An object that contains context information you want passed to the predicate function.
@return The index of the first matching object, or \c CPNotFound if there is no matching object.
*/
- (unsigned)indexOfObjectWithOptions:(CPEnumerationOptions)opts passingTest:(Function)predicate context:(id)aContext
{
// We don't use an enumerator because they return nil to indicate end of enumeration,
// but nil may actually be the value we are looking for, so we have to loop over the array.
var start, stop, increment;
if (opts & CPEnumerationReverse)
{
start = [self count] - 1;
stop = -1;
increment = -1;
}
else
{
start = 0;
stop = [self count];
increment = 1;
}
for (var i = start; i != stop; i += increment)
{
var result = predicate([self objectAtIndex:i], i, aContext);
if (typeof result === 'boolean' && result)
return i;
else if (typeof result === 'object' && result == nil)
return CPNotFound;
}
return CPNotFound;
}
/*!
Returns the index of \c anObject in the array, which must be sorted in the same order as
calling sortUsingSelector: with the selector passed to this method would result in.
+50
View File
@@ -93,6 +93,56 @@
[self assert:array equals:[@"one", @"two", @"four", nil]];
}
- (void)testIndexOfObjectPassingTest
{
var array = [CPArray arrayWithObjects:{name:@"Tom", age:7}, {name:@"Dick", age:13}, {name:@"Harry", age:27}, {name:@"Zelda", age:7}],
namePredicate = function(object, index) { return [object.name isEqual:@"Harry"]; },
agePredicate = function(object, index) { return object.age === 13; },
failPredicate = function(object, index) { return [object.name isEqual:@"Horton"]; },
noPredicate = function(object, index) { return NO; },
stopPredicate = function(object, index) { return nil; };
[self assert:[array indexOfObjectPassingTest:namePredicate] equals:2];
[self assert:[array indexOfObjectPassingTest:agePredicate] equals:1];
[self assert:[array indexOfObjectPassingTest:failPredicate] equals:CPNotFound];
[self assert:[array indexOfObjectPassingTest:noPredicate] equals:CPNotFound];
[self assert:[array indexOfObjectPassingTest:stopPredicate] equals:CPNotFound];
}
- (void)testIndexOfObjectPassingTestContext
{
var array = [CPArray arrayWithObjects:{name:@"Tom", age:7}, {name:@"Dick", age:13}, {name:@"Harry", age:27}, {name:@"Zelda", age:7}],
namePredicate = function(object, index, context) { return [object.name isEqual:context]; },
agePredicate = function(object, index, context) { return object.age === context; };
[self assert:[array indexOfObjectPassingTest:namePredicate context:@"Harry"] equals:2];
[self assert:[array indexOfObjectPassingTest:agePredicate context:13] equals:1];
}
- (void)testIndexOfObjectWithOptionsPassingTest
{
var array = [CPArray arrayWithObjects:{name:@"Tom", age:7}, {name:@"Dick", age:13}, {name:@"Harry", age:27}, {name:@"Zelda", age:7}],
namePredicate = function(object, index) { return [object.name isEqual:@"Harry"]; },
agePredicate = function(object, index) { return object.age === 7; };
[self assert:[array indexOfObjectWithOptions:CPEnumerationNormal passingTest:namePredicate] equals:2];
[self assert:[array indexOfObjectWithOptions:CPEnumerationReverse passingTest:namePredicate] equals:2];
[self assert:[array indexOfObjectWithOptions:CPEnumerationNormal passingTest:agePredicate] equals:0];
[self assert:[array indexOfObjectWithOptions:CPEnumerationReverse passingTest:agePredicate] equals:3];
}
- (void)testIndexOfObjectWithOptionsPassingTestContext
{
var array = [CPArray arrayWithObjects:{name:@"Tom", age:7}, {name:@"Dick", age:13}, {name:@"Harry", age:27}, {name:@"Zelda", age:7}],
namePredicate = function(object, index, context) { return [object.name isEqual:context]; },
agePredicate = function(object, index, context) { return object.age === context; };
[self assert:[array indexOfObjectWithOptions:CPEnumerationNormal passingTest:namePredicate context:@"Harry"] equals:2];
[self assert:[array indexOfObjectWithOptions:CPEnumerationReverse passingTest:namePredicate context:@"Harry"] equals:2];
[self assert:[array indexOfObjectWithOptions:CPEnumerationNormal passingTest:agePredicate context:7] equals:0];
[self assert:[array indexOfObjectWithOptions:CPEnumerationReverse passingTest:agePredicate context:7] equals:3];
}
- (void)testIndexOfObjectSortedByFunction
{
var array = [0, 1, 2, 3, 4, 7];