iOS - 将JSON对象转换为有序数组

时间:2016-07-21 13:23:12

标签: ios objective-c json xcode nsdictionary

我有一个带有键/值对的JSON文件,用于列出国家/地区及其国家/地区代码。我正在使用Objective-C阅读它并希望将其呈现在UIPicker中。 问题是,当我将JSON数据存储到NSDictionary时,原始订单会丢失,UIPicker元素的顺序非常随意(我知道,字典没有特定的顺序)。

保存原始订单的最简单方法是什么?我是否必须创建两个文件,一个包含国家/地区代码,另一个包含国家/地区名称,并且读入数组? - 我真的想避免那个......

[编辑]

根据请求,摘录了JSON数据(存储在本地文件中)

{"af":"Afghanistan",
    "al":"Albania",
    "dz":"Algeria",
    "as":"American Samoa",
    "ad":"Andorra",
    "ao":"Angola",
    "ai":"Anguilla",
    "aq":"Antarctica",
    "ag":"Antigua and Barbuda",
    "ar":"Argentina",
    "am":"Armenia",
    "aw":"Aruba",
    "ac":"Ascension Island (Atlantic ocean)",
    "au":"Australia",
    "at":"Austria",
    "az":"Azerbaijan",
    "bs":"Bahamas",
    "bh":"Bahrain",
    "bd":"Bangladesh",
    "bb":"Barbados",
    "by":"Belarus",
    "be":"Belgium",
    "bz":"Belize",
    "bj":"Benin",
    "bm":"Bermuda",
    "bt":"Bhutan",
    "bo":"Bolivia",
    "ba":"Bosnia",
    "bw":"Botswana",
    "bv":"Bouvet Island (Atlantic ocean)",
    "br":"Brazil",
    ... }

[编辑2]

我使用此代码读取JSON数据并将其转换为NSDictionary

NSURL *jsonPath = [[NSBundle mainBundle] URLForResource:@"countries" withExtension:@"json"];
NSString *stringPath = [jsonPath absoluteString];

NSData *countriesJSON = [NSData dataWithContentsOfURL:[NSURL URLWithString:stringPath]];

NSDictionary *parsedJson = [NSJSONSerialization JSONObjectWithData:countriesJSON options:0 error:nil];

3 个答案:

答案 0 :(得分:3)

您可以将JSON数据更改为

[
{"af":"Afghanistan"},
{"al":"Albania"},
{"dz":"Algeria"},
{"as":"American Samoa"},
{"ad":"Andorra"},
{"ao":"Angola"},
{"ai":"Anguilla"},
...
]

然后使用如下代码:

NSURL *jsonPath = [[NSBundle mainBundle] URLForResource:@"sample" withExtension:@"json"];
NSData *countriesJSON = [NSData dataWithContentsOfURL:jsonPath];
NSMutableArray *countryArray = [NSJSONSerialization JSONObjectWithData: countriesJSON options:NSJSONReadingMutableContainers error:nil];

JSON转换为名为countryArray的有序数组。 countryArray的元素是NSDictionary个实例。

答案 1 :(得分:1)

如果订单很重要并且您可以访问JSON文件,那么您可以将JSON更改为如下所示的数组:

[
    ["Afghanistan", "AF"],
    ["Bangladesh", "BD"]
]

然后当你反序列化它时,将保留顺序,因为反序列化的对象将是一个数组数组。

如果您无法访问JSON文件,则可以在代码中使用Dictionary创建此数组数组。

修改

如果您想要快速查找和排序,那么很难避免使用2个数据结构。使用您提交的JSON文件,您似乎需要一个数组:

NSArray *countriesSorted = [parsedJson.allValues sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

但是,最好将json文件中的值顺序切换为country-name:country-code。然后你可以做

NSArray *countryCodesSorted = [parsedJson.allKeys sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
NSString *firstCountryName = parsedJson[countryCodesSorted[0]];

答案 2 :(得分:1)

当需要在tableview中显示字典时,经常会出现 order 和字典的问题。对此建立的解决方案是在字典旁边保留单独的字典键数组。您可以按照您(或用户)的喜好重新排序数组,并通过数组执行两阶段的字典条目提取。这允许您保留原始JSON格式和内部存储属性/实例变量。

YourClass.m:

@interface MyClass ()
@property NSMutableArray *dictOrder;
@end

@implementation MyClass

- (void)getData
{
    self.dict = // Get dictonary from JSON
    self.dictOrder = [[self.dict allKeys] mutableCopy];
    [self.dictOrder sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
}


// UITableViewDataSource example
- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Normal cell re-use stuff
    NSString *key = self.dictOrder[indexPath.row];
    NSString *country = self.dict[key];
    // Populate cell
}

@end