9

I'm trying to make sections in a table view based on the alphabet and sort my entries alphabetically under these sections.

I have collected the first letter in every entry of bandsArray in bandsArrayIndex and I'm now trying to use NSPredicate to count how many of each letter there are.

I'm doing this by following this guide.

They are using an NSArray and I'm using an NSDictionary and can't seem to get it to work. Can anyone help me out?

The application crashes when trying to show the view with the table view in it. In Debugger Console the following error is shown:

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Can't do a substring operation with something that isn't a string

This is my code

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSString *alphabet = [bandsArrayIndex objectAtIndex:section];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF beginswith[c] %@", alphabet];
    NSArray *letters = [bandsArray filteredArrayUsingPredicate:predicate];

    return [letters count];
}

EDIT: This is my bandsArray.

The header

NSMutableArray *bandsArray;

@property (nonatomic, retain) NSMutableArray* bandsArray;

The implementation

// set array from plist
NSString *path = [[NSBundle mainBundle] pathForResource:@"Bands" ofType:@"plist"];
NSMutableArray* tmpArray = [[NSMutableArray alloc] initWithContentsOfFile:path];

self.bandsArray = tmpArray;

// sort array after name ascending
NSSortDescriptor *nameSorter = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)];
[bandsArray sortUsingDescriptors:[NSArray arrayWithObject:nameSorter]];
WrightsCS
  • 50,551
  • 22
  • 134
  • 186
simonbs
  • 7,932
  • 13
  • 69
  • 115
  • You're leaking memory like a sieve when you create `bandsArray`. – Dave DeLong Feb 04 '11 at 19:38
  • Can you show your bandsArray ? Is it just a NSString array ? I had no such problems with NSPredicate. It should be just a simple detail. If your bandsArray is not of NSStrings, you should filter by the property you're looking for. – Bruno Fuster Feb 04 '11 at 19:02

3 Answers3

22

Do you mean that bandsArray is an array of dictionaries? If so, and assuming each dictionary has a name key, you should be able to change the predicate to something like @"SELF.name beginswith[c] %@".

If, on the other hand, bandsArray is actually a dictionary itself, maybe you want to do [[bandsArray allKeys] filteredArrayUsingPredicate...].

Daniel Dickison
  • 21,832
  • 13
  • 69
  • 89
6
#import <Foundation/Foundation.h>
// clang -framework Foundation Siegfried.m 
    int
main() {
    NSArray *arr = @[
        @{@"1" : @"Fafner"},
        @{@"1" : @"Fasolt"}
    ];
    NSPredicate *p = [NSPredicate predicateWithFormat: @"SELF['1'] CONTAINS 'e'"];
    NSArray *res = [arr filteredArrayUsingPredicate:p];
    NSLog(@"Siegfried %@", res);
    return 0;
}
0

Sorry, I didnt notice you had a NSArray of NSDictionaries.

Read this thread: Using NSPredicate to filter an NSArray based on NSDictionary keys

When you use NSDictionary, you should check by its Key... I'm not sure you're using the right approach!

I would do something like: @implementation Word : NSObect { NSString *title; }

then I would create a NSArray of Words and filter on them with: @"title beginswith[c] %@"

Community
  • 1
  • 1
Bruno Fuster
  • 486
  • 5
  • 8