Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > Developer Center > Arrays, dictionaries, and other things.

Arrays, dictionaries, and other things.
Thread Tools
Mac Elite
Join Date: Oct 2000
Status: Offline
Reply With Quote
Jun 1, 2002, 04:19 PM
 
OK, I am writing an app that is somewhat secret right now. Anyways what I need to do is read in a PLIST file that's in my app's bundle. It should be an array.

Now after someone tells me how to do that.. <img border="0" title="" alt="[Wink]" src="wink.gif" />

My file is an array of dictionaries. I hope you don't mind the AppleScript like example but Cocoa never really "shows" arrays/dictionaries so:

{{name:"name 1", someotherkeyvalue:"data"}, {name:"name 2", someotherkeyvalue:"data"}, {name:"name 3", someotherkeyvalue:"data"}}

As you can see, each dictionary in the array has the key value "name". Well I want to get an array with JUST the names. So I want to get:

{"name 1", "name 2", "name 3"}

from my array of dictionaries. Possible? Thanks
     
Synotic  (op)
Mac Elite
Join Date: Oct 2000
Status: Offline
Reply With Quote
Jun 1, 2002, 04:47 PM
 
OK, someone answered both of my questions.. I'll have to come up with more later
     
Mac Elite
Join Date: Sep 2000
Location: Tempe, AZ
Status: Offline
Reply With Quote
Jun 2, 2002, 12:46 AM
 
Just in case someone else needs the answer you can get an array of all keys by sending [myDictionary allKeys]. You can also get a string describing your dictionary by passing [myDictionary description].
Geekspiff - generating spiffdiddlee software since before you began paying attention.
     
Synotic  (op)
Mac Elite
Join Date: Oct 2000
Status: Offline
Reply With Quote
Jun 2, 2002, 11:47 AM
 
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">quote:</font><hr /><font size="1" face="Geneva, Verdana, Arial, sans-serif">Originally posted by smeger:
<strong>Just in case someone else needs the answer you can get an array of all keys by sending [myDictionary allKeys]. You can also get a string describing your dictionary by passing [myDictionary description].</strong></font><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">I can also use that for reference.. we just found that the ArrayDataSource method that ibson wrote up (thanks!) could take the way the dictionary was formatted. So there was no need.

Do you by any chance know if there if there is like a [myDictionary allObjectsForKey:@"blah"] ? All I could find is an allKeysForObject :/

Basically my next question is.. As I have an array of dictionaries.. each with the key value "name" how I can I use search their values to see if the contain a string?
     
Grizzled Veteran
Join Date: Feb 2001
Location: Germany
Status: Offline
Reply With Quote
Jun 2, 2002, 12:23 PM
 
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">quote:</font><hr /><font size="1" face="Geneva, Verdana, Arial, sans-serif">Originally posted by Synotic:
<strong>[QUOTE]Originally posted by smeger:
[qb]Do you by any chance know if there if there is like a [myDictionary allObjectsForKey:@"blah"] ? All I could find is an allKeysForObject :/
</strong></font><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">that's the thing about dictionaries (well, hashtables). each key *can* only exist once. so objectForKey is what you're looking for, behind every key, there can only be one object.
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">quote:</font><hr /><font size="1" face="Geneva, Verdana, Arial, sans-serif"><strong>
Basically my next question is.. As I have an array of dictionaries.. each with the key value "name" how I can I use search their values to see if the contain a string?</strong></font><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">you'll have to iterate over them and search each of them individually. there could be any kind of object in the array, so some kind of general search function wouldn't work.
     
Mac Elite
Join Date: Sep 2000
Location: Tempe, AZ
Status: Offline
Reply With Quote
Jun 2, 2002, 02:45 PM
 
This will search an array (myArray) of NSDictionaries, each containing the key "name" for an object that matches myString.
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">NSEnumerator *arrayEnumerator = [myArray objectEnumerator];
NSDictionary *thisDictionary;

while (thisDictionary = [arrayEnumerator nextObject])
if ([[thisDictionary objectForKey: @&quot;name&quot;] isEqual: myString])
// thisDictionary matches</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">
Geekspiff - generating spiffdiddlee software since before you began paying attention.
     
Synotic  (op)
Mac Elite
Join Date: Oct 2000
Status: Offline
Reply With Quote
Jun 2, 2002, 08:04 PM
 
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">quote:</font><hr /><font size="1" face="Geneva, Verdana, Arial, sans-serif">Originally posted by smeger:
<strong>This will search an array (myArray) of NSDictionaries, each containing the key "name" for an object that matches myString.
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">NSEnumerator *arrayEnumerator = [myArray objectEnumerator];
NSDictionary *thisDictionary;

while (thisDictionary = [arrayEnumerator nextObject])
if ([[thisDictionary objectForKey: @&quot;name&quot;] isEqual: myString])
// thisDictionary matches</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif"></strong></font><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">OK, thanks I'll try it out soon Do you by any chance know how to get an image as the title of a pulldown button ala Mail? I want to recreate the search feature as accurately as possible. There doesn't seem to be a built in way to do it.. perhaps a hack?..
     
Mac Enthusiast
Join Date: Nov 2001
Status: Offline
Reply With Quote
Jun 3, 2002, 07:42 AM
 
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">quote:</font><hr /><font size="1" face="Geneva, Verdana, Arial, sans-serif">Originally posted by Synotic:
<strong>Do you by any chance know how to get an image as the title of a pulldown button ala Mail? I want to recreate the search feature as accurately as possible. There doesn't seem to be a built in way to do it.. perhaps a hack?..</strong></font><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">This is exactly what I'm doing in my app now. . If you have a pop-up button called searchPopUpButton, and an image named SearchIcon.tiff (let's say it's the magnifying glass), here's how to do it:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">[[[searchPopUpButton menu] itemAtIndex:0] setImage:[NSImage imageNamed:@&quot;SearchIcon&quot;]];</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">

<small>[ 06-03-2002, 08:46 AM: Message edited by: Ibson ]</small>
     
Synotic  (op)
Mac Elite
Join Date: Oct 2000
Status: Offline
Reply With Quote
Jun 4, 2002, 12:21 AM
 
Well I decided ditch the pull down button for a few reasons.. but I did use your image code elsewhere and it works great But I am in the final stage of my app and I just dunno what's wrong with this.. any ideas?

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">- (IBAction)searchSubsid)sender {
if ([[searchField2 stringValue] length]==0) {
mainArray = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@&quot;main&quot; ofType:@&quot;plist&quot;]];

[mainTableView setDataSource:mainArray];
} else {
NSEnumerator *arrayEnumerator = [mainArray objectEnumerator];
NSDictionary *thisDictionary;

while (thisDictionary = [arrayEnumerator nextObject]) {
NSEnumerator *subEnumerator = [[thisDictionary objectForKey:@&quot;subs&quot;] objectEnumerator];
NSDictionary *subDictionary;
NSMutableArray *foundSubs = [[NSMutableArray alloc] initWithCapacity:0];

while (subDictionary = [subEnumerator nextObject]) {
if ([[subDictionary objectForKey: @&quot;name&quot;] rangeOfString:[searchField2 stringValue] options:NSCaseInsensitiveSearch].length != 0 &#0124;&#0124; [[subDictionary objectForKey: @&quot;description&quot;] rangeOfString:[searchField2 stringValue] options:NSCaseInsensitiveSearch].length != 0) {
[foundSubs addObject:thisDictionary];
}
}
}

[mainTableView setDataSource:foundSubs];

subArray = [[foundSubs objectAtIndex:[mainTableView selectedRow]] objectForKey:@&quot;subs&quot;];
[subTableView setDataSource:subArray];

[subNameField setStringValue:[[subArray objectAtIndex:[subTableView selectedRow]] objectForKey:@&quot;name&quot;]];
[subDescriptionField setStringValue:[[subArray objectAtIndex:[subTableView selectedRow]] objectForKey:@&quot;description&quot;]];
[subImageView setImage:[NSImage imageNamed:[[subArray objectAtIndex:[subTableView selectedRow]] objectForKey:@&quot;image&quot;]]];
}
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">In this line:

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">[mainTableView setDataSource:foundSubs];</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">it's saying that foundSubs is undeclared even though I declared it here:

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">NSMutableArray *foundSubs = [[NSMutableArray alloc] initWithCapacity:0];</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">I am not sure what's wrong.. any ideas? This is basically the LAST thing I need to do with my app <img border="0" title="" alt="[Frown]" src="frown.gif" />

<small>[ 06-04-2002, 01:41 AM: Message edited by: Synotic ]</small>
     
Mac Enthusiast
Join Date: Nov 2001
Status: Offline
Reply With Quote
Jun 4, 2002, 01:26 AM
 
Did you declare foundSubs as an instance variable in your class' header file? That definitely sounds like the problem. Also remember to release in the dealloc method. That is:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">- (void)dealloc
{
[foundSubs release];
[super dealloc];
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">
     
Grizzled Veteran
Join Date: Feb 2001
Location: Germany
Status: Offline
Reply With Quote
Jun 4, 2002, 02:18 AM
 
i think there's a misunderstanding about the "datasource" here...

a "datasource" is not an object like an array or a dictionary or something.
how would the table know what data from the array goes where? suppose you had several columns, how would it distribute them across the columns?

no... that would involve assuming; something a computer would never do for you.

a "datasource" is an object that responds to a couple of methods. the methods depend on what kind of viewer you're dealing with (nsoutlineview, nstableview, ...)
if you want the data of a table to be shown, you have to implement two methods: one that supplies the number of entries in the table:

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">- (int)numberOfRowsInTableViewNSTableView *)tv</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">and one that supplies the data for every single cell in the table:

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">- (id)tableViewNSTableView *)tv objectValueForTableColumnNSTableColumn *)theC rowint)row</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">an array doesn't offer those methods, so it can't be a datasource.

you have two choices: set your controller the datasource and distinguish between all possible cases for values in your controller *or* write a small object which only serves as datasource and nothing else. that object would be given the array you want to be displayed in your table *and* it would implement the two methods mentioned above.

of course, there are lots of other methods you can implement as delegate; what to do when a rown/column/cell was clicked or double clicked, you can allow or disallow the editing of individual cells...

hope that helped.
     
Mac Enthusiast
Join Date: Nov 2001
Status: Offline
Reply With Quote
Jun 4, 2002, 02:26 AM
 
Actually, the computer is smart enough to use an array as a data source...if you add a category to NSArray--which I showed Synotic how to do (see another thread). Ahh...the power of Objective-C.
     
Grizzled Veteran
Join Date: Feb 2001
Location: Germany
Status: Offline
Reply With Quote
Jun 4, 2002, 05:24 AM
 
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">quote:</font><hr /><font size="1" face="Geneva, Verdana, Arial, sans-serif">Originally posted by Ibson:
<strong>Actually, the computer is smart enough to use an array as a data source...if you add a category to NSArray--which I showed Synotic how to do (see another thread). Ahh...the power of Objective-C.</strong></font><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">yup. but to my taste, you should have stressed the "if". sure, then it works. didn't know about that other thread.

agreed, objective-c is one of the coolest -- if not the coolest -- programming language i've ever come across.

in combination with cocoa... a dream!
     
Forum Regular
Join Date: Sep 2000
Status: Offline
Reply With Quote
Jun 4, 2002, 04:15 PM
 
Regarding the error...

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">quote:</font><hr /><font size="1" face="Geneva, Verdana, Arial, sans-serif">Originally posted by Synotic:
<strong>In this line:</strong>
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">[mainTableView setDataSource:foundSubs];</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif"><strong>it's saying that foundSubs is undeclared even though I declared it here:</strong>
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">NSMutableArray *foundSubs = [[NSMutableArray alloc] initWithCapacity:0];</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif"><strong>I am not sure what's wrong.. any ideas? This is basically the LAST thing I need to do with my app </strong></font><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">It looks like you need to declare "NSMutableArray *foundSubs" outside of the while loop, i.e. just after the "NSDictionary *thisDictionary" line. As it stands, only code inside the while loop knows that foundSubs exists. Once you leave the while loop, that variable is no longer available. Furthermore, even if it was available, it's being re-allocated and re-initialized every time through the while loop. For it to work, it would need to look something like this:

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">NSMutableArray *foundSubs = [[NSMutableArray alloc] initWithCapacity:0];
while (...) {
// Do something with foundSubs
}
// Do something else with foundSubs
[foundSubs release];</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">Hope this is of assistance...
     
Synotic  (op)
Mac Elite
Join Date: Oct 2000
Status: Offline
Reply With Quote
Jun 4, 2002, 05:52 PM
 
Yes it involved moving foundSubs out I fixed it last night thanks to everyone's help. Also this is unrelated.. but I also fixed a problem just in case someone else wants to use this code for something..

after it worked.. if you did a search and there were 2 subs in a main and they both contained the string then it would list the main twice.. so you have to have it break after finding the first occurrence.
     
   
Thread Tools
Forum Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Top
Privacy Policy
All times are GMT -5. The time now is 01:18 PM.
All contents of these forums © 1995-2011 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.7 © 2000-2011, Jelsoft Enterprises Ltd., Content Relevant URLs by vBSEO 3.3.2