I have an NSMutable array which i'm trying to remove objects from and by that to decrease
the count of number of objects on the array, and the count always stays the same,
Meaning, the remove is not working.
Here is the code (it's from the online stanford IOS development course):
- (NSMutableArray *)cards
{
if (!_cards) _cards = [[NSMutableArray alloc] init];
return _cards;
}
- (void)addCard:(Card *)card atTop:(BOOL)atTop
{
if (atTop) {
[self.cards insertObject:card atIndex:0];
} else {
[self.cards addObject:card];
}
}
- (void)addCard:(Card *)card
{
[self addCard:card atTop:NO];
}
- (Card *)drawRandomCard
{
Card* randomCard = Nil;
NSLog(#"This is the count %d",[self.cards count]);
if ([self.cards count]) {
unsigned index = arc4random() % [self.cards count];
randomCard = self.cards[index];
[self.cards removeObjectAtIndex:index];
}
return randomCard;
}
The count is always 52, even after removing the objects.
Any ideas on how to fix this?
Related
First off i have searched a lot but all methods seems to be for primitives or for whole custom objects.
My situation is this. I have a type custom objects in two different arrays. However the fields of every single objects is quite different to another with the exception of only 2 fields.
What i want is combine both of these arrays and then remove duplicates with respect to only those two fields.How can i do that. My Code so far
NSMutableArray* testArray = [eventHandler returnAllEvents];
NSMutableArray* combinedArray = [[NSMutableArray alloc]init];
NSArray* finalArray = [[NSArray alloc]init];
if (testArray.count==0) {
for (int i = 0; i<facebookData.count; i++) {
LSEvent* event = [facebookData objectAtIndex:i];
[combinedArray addObject:event];
}
finalArray = [combinedArray arrayByAddingObjectsFromArray:calendarData];
}
NSMutableArray *uniqueArray = [NSMutableArray array];
NSMutableSet *names = [NSMutableSet set];
for (id obj in finalArray) {
NSString *destinationName = [obj destinationname];
if (![names containsObject:destinationName]) {
[uniqueArray addObject:obj];
[names addObject:destinationName];
}
}
You can do sth like this
NSArray first = ...
NSMutableArray second = ... // this will be combine array
for (id someObj in first) {
if ( [second filteredArrayUsingPredicate:[self predicateForObject:someObj ]].count == 0 ){
[second addObject: someObj];
}
}
If you want to check that object exists in array using containsObject: you need to implement - (BOOL)isEqual:(id)other in your custom object.
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
}
if (!other || ![other isKindOfClass:[self class]]) {
return NO;
}
if (self.identifier == other.identifier) {
return NO;
}
return YES;
}
I am making a drawing app, and I have a NSArray with a list of all the pixels the user forget or didn't clean, what i want is make groups of that list pixels using proximity. so i can highlight all the pixel area with a black circle. this is what i got for the moment but is not grouping well
-(NSMutableArray*)orderMissingPixelsByGroups:(NSMutableArray*)missingPixels
{
NSMutableArray *finalArray=[[NSMutableArray alloc]init];
NSMutableArray *auxArray = [[NSMutableArray alloc]init];
for (int i=0; i<[missingPixels count]; i++) {
NSValue *value = [missingPixels objectAtIndex:i];
if (i<[missingPixels count]-1) {
NSValue *nextValue = [missingPixels objectAtIndex:i+1];
CGPoint point = value.CGPointValue;
CGPoint point2 = nextValue.CGPointValue;
if (abs(point.x-point2.x)<5 ) {
[auxArray addObject:[NSValue valueWithCGPoint:point]];
}
else if (abs(point.y-point2.y)<5){
[auxArray addObject:[NSValue valueWithCGPoint:point]];
}
else
{
[auxArray addObject:[NSValue valueWithCGPoint:point]];
[finalArray addObject:auxArray];
auxArray = [[NSMutableArray alloc]init];
}
}
else
{
[auxArray addObject:value];
[finalArray addObject:auxArray];
}
}
return finalArray;
}
If you have advices I will very thankful.
Yes I can imagine this is not the best approach. Try doing something like this. Note I did not test it also there is just too much room for optimizing this approach but I hope it will help you get a bit better understanding on how to create "blobs". Otherwise you can try to search for some fast approach under "blob" keyword...
- (NSMutableArray *)createBlobsFromPixels:(NSMutableArray *)pixels {
NSMutableArray *initialBlobs = [[NSMutableArray alloc] init];
for(NSValue *pixel in pixels)
{
[initialBlobs addObject:#[pixel]];
}
while (YES) {
NSIndexSet *indexSet = [self joinBlobs:initialBlobs minimumRadius:5.0f];
if(indexSet.count < 2) {
break;
}
else {
[self mergeBlobs:initialBlobs atIndexA:indexSet.firstIndex andIndexB:indexSet.lastIndex];
}
}
return initialBlobs;
}
- (NSIndexSet *)joinBlobs:(NSMutableArray *)blobs minimumRadius:(CGFloat)minRadius {
// this method will try to join 2 blobs
// if successfull it will return an index set with 2 blob indices which should be joined
// if no blobs are able to join the method will return nil
if(blobs.count < 2) {
// can not join a single blub
return nil;
}
NSUInteger count = blobs.count;
// iterate through every pair
for(NSUInteger i=0; i<count-1; i++) {
for(NSUInteger j=i+1; j<count; j++) {
NSArray *blobA = blobs[i];
NSArray *blobB = blobs[j];
// check if any of the pixels from blob A are close enough from any pixel in blob B and merge those two blobs
for(NSValue *pixelA in blobA) {
for(NSValue *pixelB in blobB) {
CGPoint pointA = [pixelA CGPointValue];
CGPoint pointB = [pixelB CGPointValue];
if(fabsf(pointA.x-pointB.x)<minRadius && fabsf(pointA.y-pointB.y)<minRadius) {
// can join these 2 blobs
NSMutableIndexSet *indexSet = [[NSMutableIndexSet alloc] init];
[indexSet addIndex:i];
[indexSet addIndex:j];
return indexSet; // returns YES as the blob can been joined
}
}
}
}
}
return nil;
}
- (void)mergeBlobs:(NSMutableArray *)blobs atIndexA:(NSUInteger)indexA andIndexB:(NSUInteger)indexB {
NSArray *blobA = blobs[indexA];
NSArray *blobB = blobs[indexB];
[blobs removeObject:blobA];
[blobs removeObject:blobB];
[blobs addObject:[blobA arrayByAddingObjectsFromArray:blobB]];
}
I want to make 1 array that will hold all of the other arrays objects and will look like this
("052-6224754","03-6475075","02-6753231")
my code is:
-(NSMutableArray*) getRecepientsPhones
{
NSMutableArray* phones = [[NSMutableArray alloc]init];
//scroll all choosed contacts and retrieve phones to nsstring
if([recepientsFromContacts count]>0)
for (int i=0; i<[recepientsFromContacts count]; i++)
{
NSMutableArray* tempArray = [[NSMutableArray alloc]init];
if(![[[recepientsFromContacts objectAtIndex:i]objectForKey:#"CPhones"]isKindOfClass:[NSNull class]])
{
[tempArray addObject:[[recepientsFromContacts objectAtIndex:i]objectForKey:#"CPhones"]];
for(int j = 0; j<[tempArray count];j++)
{
[phones addObject:[tempArray objectAtIndex:j]];
}
}
}
//lets fetch from that contact
if([personRecepient count]>0)
{
if(![[personRecepient objectForKey:#"CellPhone"]isKindOfClass:[NSNull class]])
[phones addObject:[personRecepient objectForKey:#"CellPhone"]];
}
NSLog(#"%#",phones);
return phones;
}
[[recepientsFromContacts objectAtIndex:i]objectForKey:#"CPhones"]
is 1 or more dimension array (it is array of phone numbers per person , person can have more than 1 number)
example: ("052-6224754","03-6475075")
but my function returns
("052-6224754","03-6475075"),("02-6753231")
which is not good , what should I do to make it 1 array
("052-6224754","03-6475075","02-6753231")
You should change the line
[phones addObject:[tempArray objectAtIndex:j]];
to
[phones addObjectsFromArray:[tempArray objectAtIndex:j]];
This should result in a flattened array of phone numbers.
Then you should head over to codereview.stackexchange.com because there are several issues with your code fragment.
Edit: Here's a cleaned up version of the method:
- (NSArray *)recepientsPhoneNumbers
{
NSMutableArray* phoneNumbers = [NSMutableArray array];
for (NSDictionary *dict in _recepientsFromContacts)
{
id recipientPhoneNumbers = dict[#"CPhones"];
if (recipientPhoneNumbers != [NSNull null])
[phoneNumbers addObjectsFromArray:recipientPhoneNumbers];
}
id recipientPhoneNumbers = _personRecepient[#"CellPhone"];
if (recipientPhoneNumbers != [NSNull null])
[phoneNumbers addObjectsFromArray:recipientPhoneNumbers];
NSLog(#"%#", phoneNumbers);
return phoneNumbers;
}
I applied Cocoa coding conventions, so ivars are now prefixed with underscores.
I try to find item in array by index
http://content.screencast.com/users/xdozorx/folders/Jing/media/cb5e24cf-9349-4aa2-a886-bfafb96299f5/00000051.png
here my code.
- (NSDictionary *) getItemAtIntex:(int) index inArray:(NSArray *) array
{
for (NSDictionary *item in array)
{
if (enumerateIndex == index)
{
NSLog(#"%#",item[#"comment"]);
return item;
}
else if ([item[#"childs"] count])
{
enumerateIndex ++;
[self getItemAtIntex:index inArray:item[#"childs"]];
}
}
return nil;
}
I call my method
enumerateIndex = 0;
NSDictionary *comment = [self getItemAtIntex:indexPath.row inArray:comments];
for example, with index 1, in debug I have two answers
subGL 1 -> 1
global 2
I need in response only subGL 1 -> 1
here my file https://www.dropbox.com/s/mvc21a8pl5n6xz3/commenst.json
You aren't doing anything with the return value of the recursive call. Try this:
- (NSDictionary *) getItemAtIntex:(int) index inArray:(NSArray *) array
{
for (NSDictionary *item in array)
{
if (enumerateIndex == index)
{
NSLog(#"%#",item[#"comment"]);
return item;
}
else if ([item[#"childs"] count])
{
enumerateIndex ++;
NSDictionary *result = [self getItemAtIntex:index inArray:item[#"childs"]];
if (result) {
return result;
}
}
}
return nil;
}
I made the following method to remove doubles, however it doesn't fully work. Any suggestions?
Thank you for the help,
-(NSMutableArray*)removeDuplicateCars:(NSMutableArray*)array{
NSMutableArray *noDuplicates =[[NSMutableArray alloc]init];
for (int i=0; i<[array count]; i++) {
int counter =0;
Car *car =(Car*)[array objectAtIndex:i];
if ([noDuplicates count]==0) {
[noDuplicates addObject:car];
}
for (int i=0; i<[noDuplicates count]; i++) {
Car *car2 =(Car*)[array objectAtIndex:i];
if (![car.name isEqualToString:car2.name]) {
counter++;
}
}
if (counter==[noDuplicates count]) {
[noDuplicates addObject:car];
}
}
NSLog(#"number of results = %i",[noDuplicates count]);
return noDuplicates;
}
Create an array called "addedCars" - you will use it to store the name of each unique car.
In each iteration, use [NSArray containsObject:] to check if the current name has already been added to "addedCars". If not, add the name to "addedCars" and the car to "noDuplicates". Otherwise, skip this item, as it has already been added to noDuplicates.
be sure [isEqual:] and [hash] is implemented as you expected
-(NSMutableArray*)removeDuplicateCars:(NSMutableArray*)array{
NSOrderedSet *set = [[NSOrderedSet alloc] initWithArray:array];
NSMutableArray *newArr = [NSMutableArray arrayWithCapacity:[set count]];
for (id obj in set) {
[newArr addObject:obj];
}
return newArr;
}
You used ![car.name isEqualToString:car2.name] to compare objects so I believe you want to filter objects with same name? Than you need to override [isEqual:] for Car
- (BOOL)isEqual:(id)other {
if ([other isKindOfClass:[self class]]) {
return [self.name isEuqalToString: [other name]];
}
return NO;
}
- (NSUInteger)hash {
return [self.name hash];
}
also check this question The best way to remove duplicate values from NSMutableArray in Objective-C?