1

This is a NSTableView with IB bindings to a NSArrayController, it displays all values correctly.
However it sorts the numbers only by their first char value e.g. it will put 115.31 below 2.5, and 23.9 below 4.71, etc.

It takes values from a retained NSMutableArray with Strings in it, I also tried by converting all strings to NSNumber/NSDecimalNumber, still no luck:

NSMutableArray *array1 = [[string1 componentsSeparatedByCharactersInSet: [NSCharacterSet newlineCharacterSet]] mutableCopy];

NSMutableArray *array1alt = [NSMutableArray array];

for(NSString *strNum in array1)
{
    NSNumber *number = strNum;
    [array1alt addObject:number];
}

Please help, thanks.

EDIT: This is how NSMutableArray(s) of my NSTableColumn(s) get filled:

NSMutableArray *rows = [NSMutableArray array];

for (NSUInteger i = 0; i < array1alt.count && i < array2.count && i < array3.count && i < array4.count; i++)
{
    NSMutableDictionary *row = [NSMutableDictionary dictionary];
    [row setObject:[array1alt objectAtIndex:i] forKey:@"Apples"];
    [row setObject:[array2 objectAtIndex:i] forKey:@"Oranges"];
    [row setObject:[array3 objectAtIndex:i] forKey:@"Peaches"];
    [row setObject:[array4 objectAtIndex:i] forKey:@"Plums"];
    [rows addObject:row];
}

[myArrayController2 setContent:rows2];
[aTableView reloadData];
Jeremiah Smith
  • 740
  • 6
  • 17
  • What is your data source here? A NSArrayController filled with numbers of strings or NSMutableArray filled with numbers? Either way, in for loop, you can't assign NSString to NSNumber without some conversion taking place. – Martin Berger Jun 03 '13 at 18:48

2 Answers2

1

I'm surprised that you aren't getting a compiler warning at:

NSNumber *number = strNum;

You probably want:

NSNumber *number = [NSNumber numberWithDouble:[strNum doubleValue]];

Or, more simply:

NSNumber *number = @([strNum doubleValue]);

If you don't want to deal with number conversions on the output, you could sort your original array of strings like so:

NSArray *array2 = [array1 sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
    double num1 = [obj1 doubleValue];
    double num2 = [obj2 doubleValue];
    if (num1 < num2)
        return NSOrderedAscending;
    else if (num1 > num2)
        return NSOrderedDescending;
    else
        return NSOrderedSame;
}];

If you want to use decimal numbers, you could probably do something like:

NSMutableArray *array2 = [NSMutableArray array];
for (NSString *strNum in array1)
{
    [array2 addObject:[NSDecimalNumber decimalNumberWithString:strNum]];
}

[array2 sortUsingComparator:^NSComparisonResult(NSDecimalNumber *obj1, NSDecimalNumber *obj2) {
    return [obj1 compare:obj2];
}];
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Yes, thanks that does the trick! But I now have some scattered numbers which display far too many post-decimal digits, how do I fix that? – Jeremiah Smith Jun 03 '13 at 18:32
  • Yes, I used this method http://stackoverflow.com/questions/4026135/limit-a-double-to-two-decimal-places-without-trailing-zeros but it also still shows sparingly some numbers with loads of post-decimal digits. – Jeremiah Smith Jun 03 '13 at 18:47
  • Now the problem is, it also seems, because I only fill the NSTableView with NSMutableDictionary (containing NSMutableArrays for columns), letting the app sort the data itself, makes it all wrong somehow, the values in columns don't match the other columns data. BTW I use a repeated NSTimer on repopulating and reloading the NSTableView. – Jeremiah Smith Jun 03 '13 at 19:00
  • @JeremiahSmith If you want, you could try using `NSDecimalNumber` instead of `NSNumber` (see revised answer). Or you could do the appropriate rounding when you display your table. Whichever works. – Rob Jun 03 '13 at 19:10
  • I mean the datasource for NSTableView gets all at once with NSMutableDictionary. Before that all arrays load dynamic data one after another, before the get summed together in an NSMutableDictionary, but they don't match up... – Jeremiah Smith Jun 03 '13 at 19:10
  • @JeremiahSmith It sort of depends upon what your cell for your table view is doing. If the above doesn't work, can you show us how you're creating the cell for the table view? – Rob Jun 03 '13 at 19:22
  • Your answer does do everything right (except of some numbers showing too many post-decimal digits), my own NSTableView gets somewhat filled wrongly, I'll post in my revised question the filling of each cell. – Jeremiah Smith Jun 03 '13 at 19:40
  • Yes I found the mischief, it was the fact that my arrays had been filled disparately in sizes. – Jeremiah Smith Jun 03 '13 at 19:47
  • There still was a problem of occasional numbers which do not convert to 2 decimals like 0.8100000000000001, 9.210000000000001, 8.710000000000001, 83.01000000000001. It's bizarr, but there is a pattern there... it has to do with the fact its now a double, using floatValue instead of doubleValue fixed it! – Jeremiah Smith Jun 08 '13 at 19:44
  • @JeremiahSmith Glad you fixed it. – Rob Jun 08 '13 at 19:45
0

Without seeing more code this is what i think:

If i understood correctly, you have your NSArrayController as data source.

You need to sort your data before attaching it to your table.

You have NSArrayController methods:

- (void)setSortDescriptors:(NSArray *)sortDescriptors

and

- (NSArray *)arrangeObjects:(NSArray *)objects

With this you will get sorted array to use for your table. Maybe you will need to call reloadData of your NSTableView.

I cant test these right now because i'm at my laptop right now which doesn't have MacOS :)

Martin Berger
  • 1,639
  • 3
  • 18
  • 39