3

我在尝试按顺序对我的 NSDictionary 进行排序时遇到了麻烦,已经好几个星期了,我还没有弄明白,所以我希望有人能帮我一把……

NSDictionary 数据来自 JSON 并且数据已经从服务器排序并在 JSON 中按顺序显示,但是当它检索并转换为 NSDictionary 时,顺序都是错误的......

这是 JSON

{ 
  "categories":{
   "unknownCategoryName":[
   { "key1":"value1",
     "key2":"value2"
   }],
   "unknownCategoryName1":[
   { "key1":"value1",
     "key2":"value2"
   }],
   "unknownCategoryName2":[
   { "key1":"value1",
     "key2":"value2"
   }],
   "unknownCategoryName3":[
   { "key1":"value1",
     "key2":"value2"
   }]
  }
 }

在收到 JSON 之前,不会知道类别数量及其名称,所以这就是我用来获取计数和设置 tableView 和部分的方法

NSDictionary *results = [jsonString JSONValue];

NSDictionary *all = [results objectForKey:@"categories"];
self.datasource = all;


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  {
   return [self.datasource count];
  }

 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
   NSString *title = [[self.datasource allKeys] objectAtIndex:section];
   return title;
 }

而我想要做的是列出部分和部分标题作为JSON中的顺序......而不是像这样的混乱显示

unknownCategory3
unknownCategory1
unknownCategory
unknownCategory2

“unknownCategory”是产品类别名称,它们不按字母顺序,没有任何数字,并且它们已经在JSON中排序并按顺序显示...

所以,如果你们能提供帮助,那就太好了。提前致谢...

4

4 回答 4

8

NSDictionaries 中的键没有排序,因此您必须先对键进行排序,然后才能在表视图中使用它们。因此,不要使用 [self.datasource allKeys] 来获取章节标题,而是首先创建一个排序数组:sorted = [[self.datasource allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)],然后使用该数组来获取标题:标题= [排序的objectAtIndex:section]。

编辑后回答另一个问题:

要使用排序数组将您想要的值放入表中,我认为这应该很接近。您必须将属性 NSArray *sorted 添加到您的 .h 文件中,然后在您的 .m 中添加(这是假设您的 json 的结构与您在上面发布的一样):

 NSDictionary *results = [jsonString JSONValue];
    NSDictionary *all = [results objectForKey:@"categories"];
    self.datasource = all;
    self.sorted = [[self.datasource allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        return [self.sorted count];
    }

    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
        NSString *title = [self.sorted objectAtIndex:section];
        return title;
    }

   - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return [[self.datasource valueForKey:[self.sorted objectAtIndex:section]]count];
   }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        static NSString *cellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
        }
        NSArray *theArray = [self.datasource valueForKey:[self.sorted objectAtIndex:indexPath.section]];
        NSString *text1 = [[theArray objectAtIndex:0] valueForKey:@"key1"];
        NSString *text2 = [[theArray objectAtIndex:0] valueForKey:@"key2"];
        cell.textLabel.text = [NSString stringWithFormat:@"%@\r%@",text1,text2];
        cell.textLabel.numberOfLines=0; // this set the number of lines to unlimited
        return cell;
    }

你没有说你想如何在一个表格行中显示两个不同的值——在这个例子中,我将它们连接成一个字符串,并在两者之间返回。

于 2012-04-30T15:55:29.573 回答
1

似乎是一个奇怪的 JSON。你可以这样使用

{
"categories": [
    "unknownCategoryName": [
        {
            "key1": "value1",
            "key2": "value2"
        }
    ],
    "unknownCategoryName2": [
        {
            "key1": "value1",
            "key2": "value2"
        }
    ]
]
}

如果您确实喜欢上面的内容,那么很容易排序。

对问题中提供的 JSON 进行排序

-(NSMutableArray *)getAllKeys:(NSDictionary *)jsonDictionary{

       NSDictionary *all = [results objectForKey:@"categories"];
       NSMutableArray *allKeys = [all allKeys];
       NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"self" ascending:YES];
       NSArray *sortDescriptors = [NSArray arrayWithObject: sorter]; 

       [allKeys sortUsingDescriptors:sortDescriptors]; 
       [sorter release];

       return allkeys;
   }

   -(void)createSortedDictionary{
        NSMutableDictionary *dictionaryMutable=[NSMutableDictionary dictionary];
        for(NSString *string in allkeys){

           [dictionaryMutable setObject:[all objectForKey:string] forKey:string];
        }
     }

dictionaryMutable将保存已排序的字典

于 2012-04-30T16:54:49.840 回答
0

您是编写此 JSON 还是从无法编辑的地方获取它?在我看来它格式不正确。类别应该是一个数组,当前的数组放置没有意义。如果 JSON 看起来像这样:

{ 
  categories:[
   {unknownCategoryName:
   { key1:value1,
     key2:value2
   }},
   {unknownCategoryName2:
   { key1:value1,
     key2:value2
   }}
  ]
 }

然后您可以将类别读入 NSArray,您的委托方法将如下所示(并以正确的顺序显示):

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  {
      return [categoriesArray count];
  }

 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
     NSDictionary *dict = [categoriesArray objectAtIndex:section];  
     NSString *title = [[dict allKeys] objectAtIndex:0];
     return title;
 }
于 2012-04-30T15:37:46.433 回答
0

我认为保留原始顺序的唯一方法是在从 JSON 数据创建 JSON 字符串后自己进行初始解析。如果 JSON 字符串的结构与您发布的一样,您可以使用 NSScanner 查找引号之间的字符串,然后仅选择最后一个引号后带有 [ 的字符串添加到您订购的数组中键数组。然后,您可以使用 JSON 解析器创建 NSDictionary,并通过遍历您的有序键并将其发送 valueForKey: 来获取值。

于 2012-05-01T01:15:29.513 回答