1

我必须 UITableview,包含在字典中的节标题标题,与每个标题关联的数组中的内容(这些数组创建单元格)。

没关系,很多人在这里回答了关于订购字典的问题,这很困难,等等……即使可以(不能或有困难)订购字典,它如何每次都保持相同的顺序?


例子

假设我最终得到一个包含两个部分(标题)的表格视图,每个部分包含一些单元格

声明了一个字典,它包含部分标题。

NSMutableDictionary *menuEntries;

对于这些字典条目中的每一个,关联一个不同的数组(然后用于创建和填充单元格)。我们将有两个部分(因此字典中有两个键),由于某些原因,我们使用两个不同的数组,我们将与这些键相关联

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 不能被订购,好的,但我真的觉得,在这种情况下,它以某种方式被订购。

这很令人困惑。

4

2 回答 2

2

NSDictionary每次都保持相同的顺序,但这是基于您作为键插入的对象的哈希码的任意顺序。如果字典是可变的,插入或删除对象可以改变字典中已有键的顺序。

虽然不可能对字典本身进行排序,但当然可以将其键排序到一个单独的数组中,然后按顺序遍历该数组,通过键从(无序的)字典中提取对象。

于 2012-12-12T15:10:45.223 回答
1

编辑:

你说你有

NSMutableDictionary *menuEntries;

其中填充为:

menuEntries = [[NSMutableDictionary alloc] init];
[menuEntries setObject:mainMenuArray forKey:@"First section"];
[menuEntries setObject:self.magazineMenuArray forKey:@"Second section"];

如果您希望它尊重您填充它的顺序,您应该使用 aNSMutableArray代替,例如:

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 类参考中的排序。

于 2012-12-12T16:49:55.500 回答