如何将 NSArray 拆分为按字母顺序排列的部分以与索引表视图一起使用

Posted

技术标签:

【中文标题】如何将 NSArray 拆分为按字母顺序排列的部分以与索引表视图一起使用【英文标题】:how to split NSArray into alphabetical sections for use with index tableview 【发布时间】:2011-09-18 20:57:46 【问题描述】:

我有一个 NSArray,我从数据库中获取的一些 xml 中按字母顺序对其进行了解析和排序。我现在想知道如何拆分这个数组,以便与 tableview 上的索引一起使用,以便更快地搜索。

我的表格有点不同的是它并不总是使用整个字母表,而且与大多数示例不同,我发现我使用的数据集每天都有很大的变化。..

所以我想弄清楚如何将排序后的数组拆分为不总是相同的字母部分。

正如 cocofu 指出的那样,是的,我的 sectionIndexTitlesForTableView 已经实现,我现在正在尝试将我的 nsarray 拆分为多个部分,以便滚动与 sectionIndexTitlesForTableView 一起使用。

【问题讨论】:

看看这个 SO Q&A 是否有帮助:[ALphabetic list][1]。 [1]:***.com/questions/1655119/… 对不起,我应该说我的 sectionIndexTitlesForTableView 已经设置好了。我现在要弄清楚的部分是如何将我的 NSarray 放入部分中,以便滚动与我声明的 sectionIndexTitlesForTableView 一起工作。不过谢谢你的建议。 【参考方案1】:

我将使用您在数组中使用的第一个字母创建一个 NSSet,然后从中创建一个排序数组。假设所有第一个字母的大小写都是正确的,它看起来像:

- (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;

【讨论】:

与我目前用于设置 sectionIndexTitlesForTableView 的解决方案相比,这是一个非常好的解决方案,我正在查看不久前发现的一个类似示例,该示例正在谈论这个......但没有任何代码。 . 谢谢你,现在可以玩一下。 localizedCaseInsensitiveCompare 方法中的代码是什么? 该方法内置于 NSString 中。不需要额外的代码。 太棒了,+1。只是一个小改进:[mySet addObject:[s substringWithRange:[s rangeOfComposedCharacterSequencesForRange:(NSRange)0, 1]]]; 这样你就可以安全地对抗代理对和其他组合代码片段了。【参考方案2】:

您可以像这样使用 NSPredicate 导出数据:

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

我很想听到一种更有效的方法,而不是循环或为字母表的每个字母运行 26 个 NSPredicate 语句,或者对字符进行循环并返回元素。

您可以将每个过滤后的数组存储在 NSDictionary 中,并将字母表中的所有字母作为键,然后稍后检索它并检查它是否为空(这意味着它没有该字母的元素)。我相信 BEGINSWITH 区分大小写

【讨论】:

感谢您的评论,我仍在互联网上搜索好的示例,因为索引 tableviews 的整个过程似乎非常冗长且模棱两可。我会告诉您我找到的任何解决方案,除非这里出现有用的东西。 不要在表格视图层进行排序,也许您应该在检索数据集时在模型层进行排序,因此您只需执行一次。当您创建 NSArray 时,更容易检查然后使用字母键对数组字典进行预处理,而不是稍后使用 NSPredicate 进行搜索。 我知道 mvc 是什么以及它是如何工作的。但我很难记住它在 ios 中是如何工作的,控制器(委托)和模型(类对象)是视图是 nib 吗? ?我一直在努力寻找一些东西来刷新我的记忆,但不知所措:P 是时候去找一本书再读一遍了。 这里有什么关于高效tableview索引的新东西吗?【参考方案3】:

"arr" 这里包含从数据库或解析 xml 或其他内容后获取的所有结果。

只需按升序对数组进行排序(我的代码中为 arrSortedResults)。

    - (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

【讨论】:

您好,欢迎来到 Stack Overflow,想为您的代码添加一些解释吗?

以上是关于如何将 NSArray 拆分为按字母顺序排列的部分以与索引表视图一起使用的主要内容,如果未能解决你的问题,请参考以下文章

NSArray 的值,希望按字母顺序显示在部分中。如何分配到正确的部分?

NSArray 排序和隔离

如何将NSArray排序的NSStrings拆分为NSMutableArray的NSMutableArray

用单词和数字按字母顺序排列字符串

子程序必须按字母顺序排列。真的吗?

Resharper Intellisense 可以配置为按字母顺序排序吗?