diff --git a/Foundation/CPArray/_CPArray.j b/Foundation/CPArray/_CPArray.j index 5ba2124bae..7607aa4803 100755 --- a/Foundation/CPArray/_CPArray.j +++ b/Foundation/CPArray/_CPArray.j @@ -880,6 +880,25 @@ Returns a hash for the object. Unlike Cocoa, the hash value does not take conten return join.call([self _javaScriptArrayCopy], aString); } +/*! + Returns an Array formed by applying a function to the objects in the receiver. + @param aFunction a function taking two arguments: (element, index). + @return an Array containing the transformed elements. +*/ +- (CPArray)arrayByApplyingBlock:(Function/*element, index*/)aFunction +{ + var result = [], + count = [self count]; + + for (var idx = 0; idx < count; idx++) + { + var obj = aFunction([self objectAtIndex:idx], idx); + [result addObject:obj]; + } + + return result; +} + // Creating a description of the array /*! diff --git a/Foundation/CPArray/_CPJavaScriptArray.j b/Foundation/CPArray/_CPJavaScriptArray.j index d0ed91782c..6d36a8586f 100644 --- a/Foundation/CPArray/_CPJavaScriptArray.j +++ b/Foundation/CPArray/_CPJavaScriptArray.j @@ -233,6 +233,19 @@ var concat = Array.prototype.concat, return join.call(self, aString); } +- (CPArray)arrayByApplyingBlock:(Function/*element, index*/)aFunction +{ + var result = []; + + for (var idx = 0; idx < self.length; idx++) + { + var obj = aFunction(self[idx], idx); + result.push(obj); + } + + return result; +} + - (void)insertObject:(id)anObject atIndex:(CPUInteger)anIndex { if (anIndex > self.length || anIndex < 0) @@ -335,7 +348,6 @@ var concat = Array.prototype.concat, [super addObjectsFromArray:anArray]; } - - (id)copy { return slice.call(self, 0); diff --git a/Tests/Foundation/CPArrayTest.j b/Tests/Foundation/CPArrayTest.j index 3b113fe00d..828b70efe9 100644 --- a/Tests/Foundation/CPArrayTest.j +++ b/Tests/Foundation/CPArrayTest.j @@ -705,6 +705,23 @@ [self assert:[1, [CPNull null], "3"] equals:anArray]; } +- (void)testArrayByApplyingBlock +{ + var arr = @[@"a", @"b", @"c", @"d"]; + + var mapped = [arr arrayByApplyingBlock:function(obj, idx) + { + return obj + "_" + idx; + }]; + + [self assert:[mapped count] equals:[arr count]]; + + [arr enumerateObjectsUsingBlock:function(obj, idx, stop) + { + [self assert:mapped[idx] equals:(obj + "_" + idx)]; + }]; +} + @end @implementation AlwaysEqual : CPObject