best way to get a value of a key of dictionaries stored in an array

Discussion in 'iOS Programming' started by johnmerlino, Jun 5, 2012.

  1. johnmerlino macrumors member

    Joined:
    Oct 22, 2011
    #1
    Hey all,

    I initialize an array with dictionaries:

    Code:
        remoteTableViewData = [NSArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:FALSE,@"Dynamic Fence", nil],[NSDictionary dictionaryWithObjectsAndKeys:FALSE,@"Engine Immobilizer", nil],nil];
    
    Now at some point those values can change to TRUE. When my table view loads, I want to find out the value of @"Dynamic Fence" and @"Engine Immobilizer" each of which will represent a cell in the table:

    Code:
     if ([[remoteTableViewData objectAtIndex:indexPath.row] objectForKey:@"Dynamic Fence"] == FALSE)
        {
            cell.imageView.image = [UIImage imageNamed:@"unchecked.png"];
        }
        else {
            cell.imageView.image = [UIImage imageNamed:@"checked.png"];
        }
    
    The code above is wrong. I am hard coding "dynamic fence", but rather i just want each cell to be associated with each index (nsdictionary) of the array, but not sure how to perform the check here.

    thanks for response
     
  2. TheWatchfulOne macrumors 6502

    Joined:
    Jun 19, 2009
    #2
    I'd like to help you and I think I can but I need to understand a little more about your data structure.

    Is "remoteTableViewData" a list of objects with "Dynamic Fence" and "Engine Immobilizer" being objects in the list?

    Or is "remoteTableViewData" an object with "Dynamic Fence" and "Engine Immobilizer" being properties of that object?

    A couple of things I can tell you now:
    The dictionaryWithObjectsAndKeys method will not recognise FALSE because it's no an object. What you might be looking for is [NSNumber numberWithBool: NO];

    Also, whatever your data structure is, you might look at creating a Class that describes your object. Your main array would then contain instances of that Class.

    Having these things decided and mentioned in this thread will make it easier for others to help you.:cool:
     
  3. johnmerlino thread starter macrumors member

    Joined:
    Oct 22, 2011
    #3
    This does not warrant a class. it is just a small data structure. ideally i would have an nsdictnary with keys such as @"Dynamic Fence" and values such as true and false. Problem with this is that this data populates a table and dictionaries are not indexed, so not sure how to get the true/false value.
     
  4. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #4
    Why don't you think it warrants a class? What are you trying to avoid by not having a class?

    If you're trying to save space, you might use less space with a class, because you can directly use primitive types, which must be wrapped in an object for NSArray or NSDictionary. "Wrapped in an object" is basically an unspecialized class: NSNumber. So think of it as you getting to define a perfectly specialized class (data structure), that does exactly what you need, neither more nor less.

    Plus think about the code you have to use to access the unspecialized classes. The fact that you can't figure it out suggests it's too complicated to be easily understandable. Simple things should be simple to understand. If you have to puzzle it out, you're doing it wrong. Consider the conceptual simplicity of having a perfectly specialized class.

    And if you're trying to save time, consider all the time you've burned trying to do it without a specialized class.
     
  5. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #5
    If a boolean value is what you want to store, just use the existence of the key as your test. Make your dictionaries mutable and empty when you initialize them; when the condition is true
    Code:
    [aDict setObject:@"" forKey:someKey];
    when it is false
    Code:
    [aDict setObject:nil forKey:someKey];
    and test with
    Code:
    if ( [aDict objectForKey:someKey] != nil ) {
         // handle true condition
    }
    It is kind of considered poor style to write code that modifies the underlying contents of an immutable collection (you could eventually end up compromising thread coherence if you persist in such practices).
     
  6. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    There's a class for that: NSSet. It even has a containsObject: method.

    It's unordered, so still doesn't meet all the stated criteria.


    To the OP, you should probably read Collections Programming Topics.

    First, it shows the basic collections (NSArray, NSDictionary, NSSet) and discusses their characteristics. You may even meet a new collection you didn't know before.

    Second, you'll be able to see how much hammering of square pegs into round holes you'll need in order to get ordering. For example, you might do fine simply having an NSMutableSet which you sort into an NSArray using one of the NSSet methods for returning sorted results. Or maybe NSIndexSet can be coerced into use.
     
  7. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #7
    You kind of missed my point. If the OP wants to use keys for bools, the mutable dictionary would work best, because a bool would be whether or not the key is there (pointing to something), and any number of keys can point to the same object. NSSet only stores objects, and only a single instance of each, I am not seeing how that would help. OTOH, if only fixed number of bools are needed, a subclass of NSObject would make the most sense. In fact, if I read the BNR book correctly, you can even use method names as keys just like with a dictionary, with standard getter/setter format like properties.
     
  8. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #8
    Store the key (i.e. the NSString) in the NSMutableSet. Presence indicates TRUE, absence indicates FALSE.

    Well, I'm unsure exactly what the model is myself.

    Is there a list of immutable names which are always present, and a mutable boolean corresponding to each one? Or does the list of names expand and contract? Are the names themselves mutable (e.g. user-editable) or immutable (fixed by the app)? I don't know, and I can't tell from the original code, because it's all immutable classes, which doesn't seem to match anything that's been described. I really can't guess which things are intended to be mutable and which immutable.

    And no NSDictionary or NSSet is going to represent an ordered list directly, so there's still going to be some work to get that part of the model. So really, I'm back with my earlier post: write a specialized class, instead of cobbling it together from NSDictionary and NSArray. Worst case, the specialized class uses an NSArray and/or NSDictionary internally, and encapsulates all the crapitude.
     
  9. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #9
    @johnmerlina, all you need to figure out is how to put an NSNumber numberWithBool into a dictionary and then how to read it out and get its value.

    @sydde, you can't setObject to nil. That will assert.
     
  10. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #10
    Sorry, I keep thinking -setValue:forKey: is entirely interchangeable with -setObject:forKey:
     
  11. TheWatchfulOne macrumors 6502

    Joined:
    Jun 19, 2009
    #11
    In fact, I've done that very thing. The formal term is Key-Value Coding.:cool:
     
  12. TheWatchfulOne macrumors 6502

    Joined:
    Jun 19, 2009
    #12
    This.

    And if you declare a property for each instance variable, you can use Key-Value Coding to retrieve values easily.:cool:
     

Share This Page