0

I have a need to compare a NSString variable to an object that is store in an NSDictionary that is inside an NSMutableArray

My NSMutableArray holds Manu NSDictionaries that each have two NSString objects

Before I add more entires to the Array I want to make sure its not already in there but at that point I only know one of the object names

for example

NSDictionary holds @"foo" for key @"bar" and @"Jongel" for key @"fibbel"

Now I want to build and insert a new NSDictionary into the Array but only if NSString @"foo" does not already inside a dict inside the array

I cannot find any documentation how to address an NSDictionary inside an array, I can find documentation how to find an array inside an nsdictionary by using NSArray *myArray = dict[0] and then loop through but thats what I need I need go the other way

How can this be done?

here is what I am trying but I can't get it right

+ (void) splitOutCategories:(NSMutableArray *)reveProducts {
    if([NWTillHelper isDebug] == 1) {
        NSLog(@"%s entered with array count = %lu", __PRETTY_FUNCTION__, reveProducts.count);
    }

    NSMutableArray *reveCollections = [[NSMutableArray alloc] init];

    for (NSDictionary *dictProduct in reveProducts) {
        NSMutableDictionary *dictReveCollections = [[NSMutableDictionary alloc] init];
        NSArray *arrLocales = dictProduct[@"locales"];
        for (NSDictionary *dictLocale in arrLocales) {
            NSArray *arrCategories = dictLocale[@"categories"];
            NSArray *arrImages = dictLocale[@"images"];
            if(arrCategories.count < 1) {
                // Nothing to do
            } else if (arrCategories.count == 1) {
                if(![reveCollections containsObject:arrCategories[0]]) {
                    // Here we need to build the entire dict and insert into the array
                    NSString *fcTitle = arrCategories[0];
                    NSString *fcImageUrl = arrImages[0];
                    [dictReveCollections setObject:fcTitle forKey:@"fcTitle"];
                    [dictReveCollections setObject:fcImageUrl forKey:@"fcImageUrl"];
                    [reveCollections addObject:dictReveCollections];
                }
            } else if (arrCategories.count > 1) {
                if(![reveCollections containsObject:arrCategories[1]]) {
                    NSString *fcTitle = arrCategories[1];
                    NSString *fcImageUrl = nil;
                    if(arrImages.count < 1) {
                        fcImageUrl = @"https://xxxxyyyyy.png";
                    } else {
                        fcImageUrl = arrImages[0];
                    }
                    [dictReveCollections setObject:fcTitle forKey:@"fcTitle"];
                    [dictReveCollections setObject:fcImageUrl forKey:@"fcImageUrl"];
                    [reveCollections addObject:dictReveCollections];
                }
            }
        }
    }
    NSLog(@"reveCollectionsArray = \r\n%@", reveCollections);
    NSLog(@"reveCollectionsArrayCount = %lu", reveCollections.count);
}
Matt Douhan
  • 2,053
  • 1
  • 21
  • 40
  • can you show sample structure of the entire model? starting from topmost array? – Skywalker Jun 18 '18 at 09:15
  • Possible duplicate of [Searching NSArray of NSDictionary objects](https://stackoverflow.com/questions/5846271/searching-nsarray-of-nsdictionary-objects) – Willeke Jun 18 '18 at 09:22

1 Answers1

0

Before I add more entires to the Array I want to make sure its not already in there

The solution here depends on what exactly needs to be unique. As you described, it sounds like only the value of the NSDictionary key/value pair needs to be unique ("foo", "Jongel"). If that's the case, then you can solve this very easily by using NSMutableSet to keep track of the values you've already accepted.

An approach like this would work:

@interface CollectionExample ()
@property (strong, nonatomic) NSMutableArray *reveCollections;
@property (strong, nonatomic) NSMutableSet *storedValues;
@end

@implementation CollectionExample

- (instancetype)init {
    self = [super init];
    if (self) {
        _storedValues = [NSMutableSet set];
        _reveCollections = [NSMutableArray array];
    }
    return self;
}

- (BOOL)valueAlreadyExists:(NSString *)newValue {
    return [self.storedValues containsObject:newValue];
}

- (void)addNewKeyValuePair:(NSString *)key value:(NSString *)value {
    if ([self valueAlreadyExists:value]) {
        // handle this however you'd like
        return;
    }
    NSDictionary *dict = @{key: value};
    [self.reveCollections addObject:dict];
    [self.storedValues insertObject:value];
}

@end

However, if what needs to be unique is the key/value pair, then you have to iterate over the array and iterate over each key/value pair in the each dictionary. Something like this should work:

- (BOOL)valueAlreadyExists:(NSString *)newKey value:(NSString *)newValue {
    BOOL foundPair = NO;
    for (NSDictionary *dict in self.reveCollections) {
        [dict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            if ([newKey isEqualToString:key] && [newValue isEqualToString:obj]) {
                foundPair = YES;
                *stop = YES;
                return;
            }
        }];
    }
    return foundPair;
}
Nima Yousefi
  • 817
  • 6
  • 11