How to partition NSArray alphabetically for use with an index table

I have an NSArray that I parsed and sorted alphabetically from some xml that I get from my database. Now I'm wondering how to split this array for use with a table index for faster searches.

Where my table is a little different is that it doesn't use the whole alphabet at all, and, unlike most of the examples, I found the data set that I use is changing a lot from day to day.

so I'm trying to figure out how to split a sorted array into alphabetical sections that are not always the same.

As Cocoff remarked, yes, I already have my IndexTitlesForTableView section, now I'm trying to split my nsarray into sections so that scrolling works with sectionIndexTitlesForTableView.

+4
source share
3 answers

I would create an NSSet with the first letters that you use in your array, and then create a sorted array from them. Assuming all the first letters have the correct case, it looks something like this:

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { NSMutableSet *mySet = [[[NSMutableSet alloc] init] autorelease]; for ( NSString *s in myArray ) { if ( s.length > 0 ) [mySet addObject:[s substringToIndex:1]]; } NSArray *indexArray = [[mySet allObjects] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; return indexArray; } 
+6
source

You can use NSPredicate to get this data:

 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF BEGINSWITH 'a'"]; NSArray *aElements = [myArray filterUsingPredicate:predicate]; 

I would like to hear a more efficient way, rather than a loop or the presence of 26 NSPredicate statements for each letter of the alphabet or performing a loop with characters and returning elements.

You can store each filtered array in NSDictionary with all the letters of the alphabet as keys, and then retrieve it later and check if it is empty (which means that it has no elements for that letter). I find BEGINSWITH case sensitive

+3
source

"arr" here contains all the results obtained from the database or after parsing xml or any other.

Just sort the array in ascending order (arrSortedResults in my code).

  - (void)viewDidLoad { [super viewDidLoad]; NSMutableArray *arr=[[NSMutableArray alloc]initWithObjects:@"a",@"b",@"c",@"c",@"a1",@"b1",@"c1",@"a2",@"a3",@"a4",@"b", nil]; tableGroupView=[[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 460) style:UITableViewStyleGrouped];//simply initialization of tableview tableGroupView.delegate=self; tableGroupView.dataSource=self; [self.view addSubview:tableGroupView]; NSArray *arrSortedResults= [arr sortedArrayUsingSelector:@selector(compare:)]; ArrayForArrays=[[NSMutableArray alloc]init];//initialize a array to hold arrays for section of table view BOOL checkValueAtIndex=NO; //flag to check SectionHeadsKeys=[[NSMutableArray alloc]initWithObjects:nil];//initialize a array to hold keys like A,B,C ... for(int index=0;index<[arrSortedResults count];index++) { NSMutableString *strchar=[arrSortedResults objectAtIndex:index]; NSString *sr=[strchar substringToIndex:1]; NSLog(@"%@",sr);//sr containing here the first character of each string if(![SectionHeadsKeys containsObject:[sr uppercaseString]])//here I'm checking whether the character already in the selection header keys or not { [SectionHeadsKeys addObject:[sr uppercaseString]]; TempArrForGrouping=[[NSMutableArray alloc]initWithObjects:nil]; checkValueAtIndex=NO; } if([SectionHeadsKeys containsObject:[sr uppercaseString]]) { [TempArrForGrouping addObject:[arrSortedResults objectAtIndex:index]]; if(checkValueAtIndex==NO) { [ArrayForArrays addObject:TempArrForGrouping]; checkValueAtIndex=YES; } } } } //after this ArrayForArrays will contain all the arrays which will become groups under the header headerkeys - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return [ArrayForArrays count]; } - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { return [SectionHeadsKeys objectAtIndex:section]; } - (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section { NSArray *arr= [ArrayForArrays objectAtIndex:section]; return [arr count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *SimpleTableIdentifier = @"SimpleTableIdentifier"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier]; if(cell == nil) { cell =[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier]; } int section=[indexPath section]; NSArray *arr=[ArrayForArrays objectAtIndex:section]; cell.textLabel.text=[arr objectAtIndex:indexPath.row]; return cell; } now output will be as bellow: ![enter image description here][1] [1]: http://i.stack.imgur.com/tcPr6.png 
-1
source

All Articles