iOS - 将 JSON 对象转换为有序数组
Posted
技术标签:
【中文标题】iOS - 将 JSON 对象转换为有序数组【英文标题】:iOS - Convert a JSON object to an ordered array 【发布时间】:2016-07-21 13:23:12 【问题描述】:我有一个 JSON 文件,其中包含国家列表及其国家代码的键/值对。我正在使用 Objective-C 阅读它,并希望在 UIPicker
中呈现它。
问题是,当我将 JSON 数据存储到 NSDictionary
中时,原始顺序会丢失,UIPicker
元素的顺序非常随意(我知道,字典没有特定顺序)。
保持原始订单最简单的方法是什么?我是否必须创建两个文件,一个带有国家代码,一个带有国家名称,并以相同的顺序读入一个数组? - 我真的很想避免这种情况......
[编辑]
根据请求,JSON-Data 的摘录(存储在本地文件中)
"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];
【问题讨论】:
能否分享一下你收到数据的json格式 将 JSON 数组转换为 NSDictionary 的代码是什么What's the easiest way to preserve to original order?
Dictionary 不是有序容器。没有原始订单之类的东西。如果要排序,请先排序。
@Desdenova:如您所见,原始 JSON 数据是有序的。当我将 JSON 数据转换为 NSDictionary 时,它就会丢失。因此我的问题;)
不,不是。下次打印时,您可能会收到相同的订单,也可能不会。
【参考方案1】:
您可以将 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 被转换为名为@987654323@ 的有序数组。 countryArray
的元素是 NSDictionary
实例。
【讨论】:
谢谢 Cokile。有点像斯肯塞尔的建议,正好相反...... ;) 我会试一试你的两个建议。太糟糕了,如果不改变原始文件就不可能做到这一点...... @Swissdude 好的。但是你的代码有问题。无需创建stringPath
。只需使用[NSData dataWithContentsOfURL:jsonPath]
再次感谢 CokileCeoi。我用了你的版本。是最简单的方法... - 感谢 stringPath 的提示 - 我不知道这是从哪里来的(我猜是从某个网页复制粘贴...)【参考方案2】:
如果顺序很重要并且您可以访问 JSON 文件,那么您可以将您的 JSON 更改为如下所示的数组:
[
["Afghanistan", "AF"],
["Bangladesh", "BD"]
]
然后当你反序列化它时,顺序将被保留,因为反序列化的对象将是一个数组数组。
如果您无权访问您的 JSON 文件,那么您可以在代码中从您的字典创建这个数组数组。
编辑
如果您想要快速查找和排序,那么很难避免使用 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]];
【讨论】:
感谢您的回答。我确实可以访问 JSON 文件。如果没有其他解决方案,我会尝试您的建议...【参考方案3】:order和字典的问题经常出现在字典需要在tableview中展示的时候。已建立的解决方案是在字典旁边保留一个单独的字典键数组。您可以根据自己(或用户)的喜好对数组重新排序,并通过数组对字典条目进行两阶段提取。这允许您保留原始 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
【讨论】:
感谢 Droppy - 有趣的方法。我选择了 CokileCeoi 的解决方案 - 工作量最少;)以上是关于iOS - 将 JSON 对象转换为有序数组的主要内容,如果未能解决你的问题,请参考以下文章