我必须使用UITableview,包含在词典中的章节标题,与每个标题相关联的数组中的内容(这些数组创建单元格)。
很多人都在这里回答有关订购词典的问题,这是非常困难的等等...... 即使一个词典可以(或者有困难)被命令,它每次都如何保持相同的顺序?
示例
假设我最终得到一个包含两个部分(标题)的表视图,每个部分包含一些单元格
声明了一个词典,它包含章节标题。
NSMutableDictionary *menuEntries;
对于每个dictionnary条目,关联一个不同的数组(然后用于创建和填充单元格)。我们将有两个部分(因此在dictionnary中有两个键),由于某些原因我们使用两个不同的数组,我们将与这些键关联
NSArray *mainMenuArray;
NSMutableArray *magazineMenuArray;
第一个填充像这样(
mainMenuArray = [[NSArray alloc] initWithObjects: btn1,btn2,btn3,btn4,nil];
第二个数组(magazineMenuArray)是通过一些json调用填充的(这里没有显示如何,但是每个都可以正常工作)
所以我们最终设置了字典
menuEntries = [[NSMutableDictionary alloc] init];
[menuEntries setObject:mainMenuArray forKey:@"First section"];
[menuEntries setObject:self.magazineMenuArray forKey:@"Second section"];
最后,它运行得很好,我们已经为数组的对象定义了一些属性,一个用于标题,一个用于要调用的动作,非常酷。
!!但是!!
第二部分出现在第一部分之前。什么都不做/反对它。总是
我可以听到NSDictionnary不能被命令,好吧,但我觉得,在这种情况下,它会以某种方式被命令。
这非常令人困惑。
答案 0 :(得分:2)
NSDictionary
每次都保持相同的顺序,但这是基于您作为键插入的对象的哈希码的任意顺序。如果字典是可变的,插入或删除对象可以改变字典中已经存在的键的顺序。
虽然无法对字典本身进行排序,但当然可以将其键排序到一个单独的数组中,然后按顺序遍历该数组,从(无序)字典中按键拉出对象。
答案 1 :(得分:1)
修改强>
你说你有
NSMutableDictionary *menuEntries;
填充为:
menuEntries = [[NSMutableDictionary alloc] init];
[menuEntries setObject:mainMenuArray forKey:@"First section"];
[menuEntries setObject:self.magazineMenuArray forKey:@"Second section"];
如果您希望它遵守您填充它的顺序,则应使用NSMutableArray
代替,例如:
NSMutableArray *menuEntries;
然后,您可以使用字典条目填充该数组,至少包含两个键,用于该部分标题的内容以及包含该部分行的内容。因此:
menuEntries = [[NSMutableArray alloc] init];
[menuEntries addObject:[NSDictionary dictionaryWithObjectsAndKeys:
@"First section", @"title",
mainMenuArray, @"rows",
nil]];
[menuEntries addObject:[NSDictionary dictionaryWithObjectsAndKeys:
@"Second section", @"title",
self.magazineMenuArray, @"rows",
nil]];
因此,
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [menuEntries count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSDictionary *section = [menuEntries objectAtIndex:section];
return [section objectForKey:@"title"];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSDictionary *section = [menuEntries objectAtIndex:section];
return [[section objectForKey:@"rows"] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *section = [menuEntries objectAtIndex:indexPath.section];
NSArray *rows = [section objectForKey:@"rows"];
id row = [rows objectAtIndex:indexPath.row];
// I didn't know how mainMenuArray and self.magazineMenuArray were populated,
// so I used a data type of `id` for the row, but you can obviously replace
// that with whatever is appropriate, e.g., NSDictionary* or whatever.
// proceed with the configuring of the cell here
}
就个人而言,我不会在整个地方使用文字字符串@"title"
和@"rows"
,而是定义如下所示的常量,在实现开始时包含这些,并使用它们代替文字字符串。但我相信你会得到基本的想法。
NSString * const kTableTitleKey = @"title";
NSString * const kTableRowsKey = @"rows";
无论如何,这概述了我在UITableView
对象后面使用的非常常见的数据模型。这是一个很好的逻辑结构,对应于表视图本身。本质上它是一个部分数组,每个部分都是一个带有两个键的字典,一个用于标题,一个用于该部分的行。 “节的行”的值本身就是一个数组,表的每一行都有一个条目。这听起来很复杂,但正如您在上面所看到的,它实际上使实现变得非常非常简单。
在OP提供有关数据结构性质的任何信息之前,我提供了原始答案。因此,我提供了一个更抽象的问题的答案,即如何对字典条目数组进行排序。不过,我保留这个答案作为历史参考:
原始回答:
我不确定你是如何存储字典以及如何在表中表示行的,但常见的模式是拥有一组字典项:
NSArray *array = @[
@{@"id" : @"1", @"name":@"Mo", @"age":@25},
@{@"id" : @"2", @"name":@"Larry", @"age":@29},
@{@"id" : @"3", @"name":@"Curly", @"age":@27},
@{@"id" : @"4", @"name":@"Shemp", @"age":@28}
];
然后您可以通过name
对其进行排序,如下所示:
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"name"
ascending:YES];
NSArray *sortedArray = [array sortedArrayUsingDescriptors:@[descriptor]];
NSLog(@"array = %@", array);
NSLog(@"sortedArray = %@", sortedArray);
有一系列排序方法,因此请查看 NSArray类参考中的Sorting。