Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don't worry, you can still create the pull request.
  • 2 commits
  • 3 files changed
  • 7 commit comments
  • 1 contributor
View
2  Source/Model/MJGSortedMutableArray.h
@@ -21,6 +21,8 @@
- (id)initWithSelector:(SEL)selector;
- (NSUInteger)addObject:(id)obj;
+- (NSArray*)addObjects:(NSArray*)objects;
+- (void)addObjects:(NSArray*)objects addedIndices:(NSUInteger*)indices;
- (void)removeObjectAtIndex:(NSUInteger)index;
- (void)removeAllObjects;
- (id)objectAtIndex:(NSUInteger)index;
View
30 Source/Model/MJGSortedMutableArray.m
@@ -106,6 +106,36 @@ - (NSUInteger)addObject:(id)obj {
return addedIndex;
}
+- (NSArray*)addObjects:(NSArray*)objects {
+ NSUInteger *indices = malloc(sizeof(NSUInteger) * objects.count);
+ [self addObjects:objects addedIndices:indices];
+
+ NSMutableArray *returnArray = [NSMutableArray new];
+ for (NSUInteger i = 0; i < objects.count; i++) {
+ [returnArray addObject:[NSNumber numberWithUnsignedInteger:indices[i]]];
+ }
+
+ if (indices) {
+ free(indices);
+ }
+
+ return [returnArray copy];
+}
+
+- (void)addObjects:(NSArray*)objects addedIndices:(NSUInteger*)indices {
+ [objects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+ NSUInteger index = [self addObject:obj];
+ if (indices) {
+ indices[idx] = index;
+ for (NSUInteger i = 0; i < idx; i++) {
+ if (indices[i] >= index) {
+ indices[i] = indices[i] + 1;
+ }
+ }
+ }
+ }];
+}
+
- (void)removeObjectAtIndex:(NSUInteger)index {
[_backingArray removeObjectAtIndex:index];
}
View
21 Tests/MJGSortedMutableArrayTests/Source/MJGSortedMutableArrayTests.m
@@ -89,4 +89,25 @@ - (void)testEnumerating {
}
}
+- (void)testMultipleInsertion {
+ NSArray *descriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"intValue" ascending:YES]];
+ self.array = [[MJGSortedMutableArray alloc] initWithDescriptors:descriptors];
+
+ NSArray *objectsToAdd = [[NSArray alloc] initWithObjects:
+ [NSNumber numberWithInt:0],
+ [NSNumber numberWithInt:2],
+ [NSNumber numberWithInt:4],
+ [NSNumber numberWithInt:1],
+ [NSNumber numberWithInt:3],
+ nil];
+ NSArray *addedIndices = [_array addObjects:objectsToAdd];
+
+ STAssertEquals(addedIndices.count, (NSUInteger)5, @"Incorrect number of indices returned");
+ STAssertEquals([[addedIndices objectAtIndex:0] unsignedIntegerValue], (NSUInteger)0, @"Incorrect index returned");
+ STAssertEquals([[addedIndices objectAtIndex:1] unsignedIntegerValue], (NSUInteger)2, @"Incorrect index returned");
+ STAssertEquals([[addedIndices objectAtIndex:2] unsignedIntegerValue], (NSUInteger)4, @"Incorrect index returned");
+ STAssertEquals([[addedIndices objectAtIndex:3] unsignedIntegerValue], (NSUInteger)1, @"Incorrect index returned");
+ STAssertEquals([[addedIndices objectAtIndex:4] unsignedIntegerValue], (NSUInteger)3, @"Incorrect index returned");
+}
+
@end

Showing you all comments on commits in this comparison.

@mikeabdullah

Rather than messing around with NSNumber or C arrays, I suggest implementing a single -addObjectsFromArray: method that returns an NSIndexSet

@mattjgalloway

Yep that would be nicer. I'd still like to expose the C-array style interface (although it does need documenting as you have to free() it) but yes it should be an NSIndexSet. Pull requests accepted :-).

@mikeabdullah

Why are you interested in keeping the C-array style interface? What benefit does it have?

@mattjgalloway

It's quicker if you know what you're doing with it. Although, granted, the "overhead" of creating the NSIndexSet really won't be all that much. Perhaps premature optimisation I must admit.

@mikeabdullah

I suspect in reality it would not be the bottleneck. If you particularly need to add a large number of objects at once, I'd expect to find that the bottleneck is either:

  • Creating the index set or C array. Both have a similar cost as both are allocating memory; iterating the array yourself and calling -addObject: is faster
  • Inserting the objects into the underlying storage. In which case, using -insertObjects:atIndexes: internally is the answer, as it gives NSMutableArray a better idea of its allocation needs, and therefore you've already spent time to create an index set
@mattjgalloway

I agree with you. In my particular use case I wanted the C-array method exposed but I agree that for the general case it might not be best exposed. I'll take a look as soon as I get time to making it use NSIndexSet, not expose the C-array method and inheriting from NSArray. In the meantime, pull requests are gladly accepted.

@mikeabdullah

Great! I'll dive in myself if I get a chance

Something went wrong with that request. Please try again.