 |
 |
Arrays, dictionaries, and other things.
|
 |
|
 |
|
Mac Elite
Join Date: Oct 2000
Status:
Offline
|
|
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 
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: Oct 2000
Status:
Offline
|
|
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
|
|
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.
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: Oct 2000
Status:
Offline
|
|
</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
|
|
</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
|
|
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: @"name"] 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.
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: Oct 2000
Status:
Offline
|
|
</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: @"name"] 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
|
|
</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:@"SearchIcon"]];</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">
<small>[ 06-03-2002, 08:46 AM: Message edited by: Ibson ]</small>
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: Oct 2000
Status:
Offline
|
|
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)searchSubs  id)sender {
if ([[searchField2 stringValue] length]==0) {
mainArray = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"main" ofType:@"plist"]];
[mainTableView setDataSource:mainArray];
} else {
NSEnumerator *arrayEnumerator = [mainArray objectEnumerator];
NSDictionary *thisDictionary;
while (thisDictionary = [arrayEnumerator nextObject]) {
NSEnumerator *subEnumerator = [[thisDictionary objectForKey:@"subs"] objectEnumerator];
NSDictionary *subDictionary;
NSMutableArray *foundSubs = [[NSMutableArray alloc] initWithCapacity:0];
while (subDictionary = [subEnumerator nextObject]) {
if ([[subDictionary objectForKey: @"name"] rangeOfString:[searchField2 stringValue] options:NSCaseInsensitiveSearch].length != 0 || [[subDictionary objectForKey: @"description"] rangeOfString:[searchField2 stringValue] options:NSCaseInsensitiveSearch].length != 0) {
[foundSubs addObject:thisDictionary];
}
}
}
[mainTableView setDataSource:foundSubs];
subArray = [[foundSubs objectAtIndex:[mainTableView selectedRow]] objectForKey:@"subs"];
[subTableView setDataSource:subArray];
[subNameField setStringValue:[[subArray objectAtIndex:[subTableView selectedRow]] objectForKey:@"name"]];
[subDescriptionField setStringValue:[[subArray objectAtIndex:[subTableView selectedRow]] objectForKey:@"description"]];
[subImageView setImage:[NSImage imageNamed:[[subArray objectAtIndex:[subTableView selectedRow]] objectForKey:@"image"]]];
}
}</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
|
|
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
|
|
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)numberOfRowsInTableView  NSTableView *)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)tableView  NSTableView *)tv objectValueForTableColumn  NSTableColumn *)theC row  int)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
|
|
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
|
|
</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
|
|
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...
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: Oct 2000
Status:
Offline
|
|
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.
|
|
|
| |
|
|
|
 |
 |
|
 |
|
|
|
|
|

|
|
 |
Forum Rules
|
 |
 |
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is Off
|
|
|
|
|
|
 |
 |
 |
 |
|
 |
|