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 > Sorted array or dictionary

Sorted array or dictionary
Thread Tools
VEGAN
Senior User
Join Date: Jun 2002
Location: UK
Status: Offline
Reply With Quote
Sep 3, 2002, 04:30 AM
 
I'm having troubles with "sortedArrayUsingSelector:"

Obviously, I'm doing something wrong

I'm missing documentation about the @selector, I think. What do I have to put into the @selector()? I just need to make a simple [ascending or descending] array.
     
VEGAN  (op)
Senior User
Join Date: Jun 2002
Location: UK
Status: Offline
Reply With Quote
Sep 3, 2002, 04:41 AM
 
What am I missing? Isn't this how it should be?

[myArray setArray:[[[myDict objectForKey:@"myKey"] allValues] sortedArrayUsingSelector:@selector(compare:)]];
     
Ibson
Mac Enthusiast
Join Date: Nov 2001
Status: Offline
Reply With Quote
Sep 3, 2002, 04:49 AM
 
What does your array contain? Strings, numbers, what? For strings, you can use caseInsensitiveCompare:, and for numbers, compare:
     
VEGAN  (op)
Senior User
Join Date: Jun 2002
Location: UK
Status: Offline
Reply With Quote
Sep 3, 2002, 04:59 AM
 
Originally posted by Ibson:
What does your array contain? Strings, numbers, what? For strings, you can use caseInsensitiveCompare:, and for numbers, compare:
Hm...
The result was this:

2002-09-03 10:51:17.106 WeightTracker[4513] *** -[NSCFDictionary caseInsensitiveCompare:]: selector not recognized
2002-09-03 10:51:17.130 WeightTracker[4513] An uncaught exception was raised
2002-09-03 10:51:17.147 WeightTracker[4513] *** -[NSCFDictionary caseInsensitiveCompare:]: selector not recognized
2002-09-03 10:51:17.169 WeightTracker[4513] *** Uncaught exception: <NSInvalidArgumentException> *** -[NSCFDictionary caseInsensitiveCompare:]: selector not recognized

I'm realizing that something is not right.
Let me restate what I'm doing.

I want to sort by the first column, so to say, not across row. I just realized that I'm not telling anywhere that it should be sorted by first column, am I?
     
Ibson
Mac Enthusiast
Join Date: Nov 2001
Status: Offline
Reply With Quote
Sep 3, 2002, 05:02 AM
 
What is the structure of your dictionary? If you want to sort by a value for key in your dictionary, you will have to write a custom sorting selector. Just post the -description of your dictionary.
     
VEGAN  (op)
Senior User
Join Date: Jun 2002
Location: UK
Status: Offline
Reply With Quote
Sep 3, 2002, 05:08 AM
 
Originally posted by Ibson:
What is the structure of your dictionary? If you want to sort by a value for key in your dictionary, you will have to write a custom sorting selector. Just post the -description of your dictionary.
"03/09/2002 02:53" = {
Date = "03/09/2002 02:53";
"Days to target" = "";
Difference = "";
Weight = 60;
};
"03/09/2002 03:01" = {
Date = "03/09/2002 03:01";
"Days to target" = "";
Difference = "";
Weight = 58;
};
"03/09/2002 03:08" = {
Date = "03/09/2002 03:08";
"Days to target" = "";
Difference = "";
Weight = 67;
};
"03/09/2002 03:19" = {
Date = "03/09/2002 03:19";
"Days to target" = "";
Difference = "";
Weight = 61;
};
"03/09/2002 03:30" = {
Date = "03/09/2002 03:30";
"Days to target" = "";
Difference = "";
Weight = 58;
};
"03/09/2002 03:41" = {
Date = "03/09/2002 03:41";
"Days to target" = "";
Difference = "";
Weight = 59;
};
"03/09/2002 10:44" = {
Date = "03/09/2002 10:44";
"Days to target" = "";
Difference = "";
Weight = 65;
};
     
Ibson
Mac Enthusiast
Join Date: Nov 2001
Status: Offline
Reply With Quote
Sep 3, 2002, 05:17 AM
 
You can't sort a dictionary, so (as you have) get an array using the -allValues method. If you want to sort by the date column (I'm assuming the dates are NSDate objects; if not, they should be) do this:
Code:
NSArray *arrayToSort; NSArray *sortedArray; arrayToSort = [myDict allValues]; sortedArray = [arrayToSort sortedArrayUsingSelector:@selector(dateValueCompare:)];
Then add this category to NSDictionary somewhere else in your file:
Code:
@implementation NSDictionary (DictionaryDateSorting) - (NSComparisonResult)dateValueCompare:(NSDictionary *)otherDictionary { return [(NSDate *)[self valueForKey:@"Date"] compare:[otherDictionary valueForKey:@"Date"]]; } @end
     
VEGAN  (op)
Senior User
Join Date: Jun 2002
Location: UK
Status: Offline
Reply With Quote
Sep 3, 2002, 05:33 AM
 
I had to modify it a bit but YESSSSSSSSSSSS!!!!!!!
IT WORKS NOW!!!

Thanks a million!
     
Detrius
Professional Poster
Join Date: Apr 2001
Location: Asheville, NC
Status: Offline
Reply With Quote
Sep 5, 2002, 01:11 AM
 
Just to add my $.02:

I like the [NSArray* sortedArrayUsingFunction: context: ]. This way, you define your function as a C function and pass the function name rather simply. For example:

currentArray = [[[aDictionarry allValues]
sortedArrayUsingFunction: sortObjects context: NULL] retain];


function definition:

Code:
int sortObjects(CamerasTree *aTree,CamerasTree *bTree,void *context) { if ([aTree getNumber] < [bTree getNumber]) { //NSLog(@"NSOrderedAscending"); return NSOrderedAscending; } if ([aTree getNumber] > [bTree getNumber]) { //NSLog(@"NSOrderedDescending"); return NSOrderedDescending; } //NSLog(@"NSOrderedSame"); return NSOrderedSame; }


Note that I am setting up an NSOutlineView using a tree system that I have set up using NSDictionary. The stuff that gets displayed must be sorted first. That's how I did it.
ACSA 10.4/10.3, ACTC 10.3, ACHDS 10.3
     
VEGAN  (op)
Senior User
Join Date: Jun 2002
Location: UK
Status: Offline
Reply With Quote
Sep 5, 2002, 02:46 AM
 
Originally posted by Detrius:
Just to add my $.02:

I like the [NSArray* sortedArrayUsingFunction: context: ]. This way, you define your function as a C function and pass the function name rather simply. For example:

currentArray = [[[aDictionarry allValues]
sortedArrayUsingFunction: sortObjects context: NULL] retain];


function definition:

Code:
int sortObjects(CamerasTree *aTree,CamerasTree *bTree,void *context) { if ([aTree getNumber] < [bTree getNumber]) { //NSLog(@"NSOrderedAscending"); return NSOrderedAscending; } if ([aTree getNumber] > [bTree getNumber]) { //NSLog(@"NSOrderedDescending"); return NSOrderedDescending; } //NSLog(@"NSOrderedSame"); return NSOrderedSame; }
Don't get me wrong but let me ask this:

How is your code "better"?

I mean, if I look at the number of lines I'd say that yours is longer, i.e., takes longer to write. So....?
     
Detrius
Professional Poster
Join Date: Apr 2001
Location: Asheville, NC
Status: Offline
Reply With Quote
Sep 5, 2002, 09:13 AM
 
Originally posted by VEGAN:


Don't get me wrong but let me ask this:

How is your code "better"?

I mean, if I look at the number of lines I'd say that yours is longer, i.e., takes longer to write. So....?
I think it's more straightforward. It's also something that actually makes sense from the developer's documentation. The other way requires that the comparison already be written. So, if you are comparing home-made data types, the other way won't work at all without adding more lines... more specifically, something like what I already wrote.

It doesn't involve modifying other people's classes. It could easily be modified to work in other cases.

I'm not saying yours is bad. I was just saying that in my case, mine was better.
ACSA 10.4/10.3, ACTC 10.3, ACHDS 10.3
     
mythrndr
Fresh-Faced Recruit
Join Date: Mar 2002
Location: Champaign, IL
Status: Offline
Reply With Quote
Sep 5, 2002, 02:57 PM
 
Ibson,

What is your reasoning for making the sorting method a category, rather than a method in his dictionaries sub class? The reason I ask is that the category you have written has code that is specific to his dictionary (the date key). I'm just wondering if there is some rationale I have missed.

Thanks!

Jeff
Jeff Thompson
CTO, CodeTek Studios, Inc.
Codetek VirtualDesktop -> The Mac OS X Killer Desktop App - http://www.codetek.com/
     
Ibson
Mac Enthusiast
Join Date: Nov 2001
Status: Offline
Reply With Quote
Sep 6, 2002, 01:38 AM
 
Originally posted by mythrndr:
Ibson,

What is your reasoning for making the sorting method a category, rather than a method in his dictionaries sub class? The reason I ask is that the category you have written has code that is specific to his dictionary (the date key). I'm just wondering if there is some rationale I have missed.

Thanks!

Jeff
What subclass? Vegan didn't subclass NSDictionary; in fact, there should be almost no need to subclass it. The fact that's this method is only useful for this dictionary is irrelevant.

Also, I'm not a big fan of using C-functions as comparators; the Objective-C paradigm is that one sends a message to an object if the receiver can perform a specific action. So, if we want to compare one object to another, it is logical that we send it a message. in similar vein to -isEqual:. Both a function and a method need the same amount of code; it's just my belief that using a method is a much nicer an more OO solution.
     
Angus_D
Addicted to MacNN
Join Date: Mar 2000
Location: London, UK
Status: Offline
Reply With Quote
Sep 7, 2002, 06:36 AM
 
Well, there is an overhead in sending messages to obj-c objects, unless of course Apple is clever and caching the IMPs (and even then there might be a small overhead, not sure). So, if you have a large array/dict/whatever, using a C function for a comparator might be slightly faster.
     
Ibson
Mac Enthusiast
Join Date: Nov 2001
Status: Offline
Reply With Quote
Sep 7, 2002, 06:59 AM
 
Originally posted by Angus_D:
Well, there is an overhead in sending messages to obj-c objects, unless of course Apple is clever and caching the IMPs (and even then there might be a small overhead, not sure). So, if you have a large array/dict/whatever, using a C function for a comparator might be slightly faster.
I would hope that the IMPs are cached. Then there would be a *very* small overhead, as you have to call methodForSelector: once. As for C-functions being faster, that's certainly true, but where do you draw the line? Why don't we just write everything using C ...there's a limit.
     
   
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
Top
Privacy Policy
All times are GMT -4. The time now is 04:43 AM.
All contents of these forums © 1995-2017 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.8 © 2000-2017, Jelsoft Enterprises Ltd.,