如何在swift 4中对数组中的JSON数据进行排序
Posted
技术标签:
【中文标题】如何在swift 4中对数组中的JSON数据进行排序【英文标题】:How to sort JSON Data in Array in swift 4 【发布时间】:2018-04-25 08:17:38 【问题描述】:我有这样的 JSON 数组
var json = NSArray() // array with json objects
//print json >>
json = (
Name = "Alen";
Score = 500;
,
Name = "John";
Score = 0;
,
Name = "Mark";
Score = 2000;
,
Name = "Steve";
Score = 300;
,
Name = "Ricky";
Score = 900;
)
我可以访问它的对象
(json[0] as! NSDictionary).object(forKey: "Name")
(json[0] as! NSDictionary).object(forKey: "Score")
我想根据分数对这个 JSON 数组进行排序。
我找到了类似的答案
let sortedArray = json.sorted(by: $0.0 < $1.0 )
报错
“任何”类型的值没有成员“0”
然后我尝试了这个
let sortedArray = (json as! NSDictionary).sorted (aDic, bDic) -> Bool in
return aDic.key < bDic.key
报错了
二元运算符 '
你能指导我在swift 4中根据分数对数组进行排序吗?
【问题讨论】:
问题的标题是 Swift 4 并用 Swift 3 标记,奇怪。另外,避免在 Swift 中使用 NSDictionary/NSArra,使用 Swift 字典/数组,事件更好:在 Swift 3 中可用时避免使用 NSStuff。var json
到目前为止是 not JSON,它只是 NSDictionary
的 NSArray
。正如@Larme 提到的,如果可以的话,你应该避免使用这些人,使用原生 Swift 集合(例如[[String: Int]]
)。
看起来您忘记将字典转换为对象(使用结构或类),这将极大地帮助管理这些数据。您应该避免直接使用 JSON 和字典,最好使用模型对象。
对不起,我对 swift 很陌生,我不知道该怎么做..
@FaizyZaidy 看看 vadian 的回答。
【参考方案1】:
这是一个很好的例子,为什么强烈建议您不要在 Swift 中使用 NSArray
和 NSDictionary
。
两种集合类型都不提供类型信息,因此所有内容都被视为Any
。 Swift 标准库的大多数共享泛型 API 不能与 Any
一起使用,因此除非添加很多丑陋的类型转换,否则您无法利用强大的泛型函数。
如果所有值都是String
,则将您的数组声明为
var json = [[String:String]]()
然后你可以用
对数组进行排序let sortedArray = json.sorted $0["Score"]! < $1["Score"]!
最推荐的解决方案是将 JSON 直接解码为自定义结构
struct Player : Decodable
let name : String
let score : String
private enum CodingKeys : String, CodingKey case name = "Name", score = "Score"
然后你摆脱所有类型转换,你可以按属性名称排序
var players = [Player]()
let jsonString = """
["Name" : "Alen", "Score" : "500",
"Name" : "John", "Score" : "0",
"Name" : "Mark", "Score" : "2000",
"Name" : "Steve", "Score" : "300",
"Name" : "Ricky", "Score" : "900"]
"""
let data = Data(jsonString.utf8)
do
players = try JSONDecoder().decode([Player].self, from: data)
let sortedPlayers = players.sorted $0.score.compare($1.score, options: .numeric) == .orderedAscending
print(sortedPlayers)
catch print(error)
编辑:
使用异步方式加载 JSON (URLSession
)
永远不要从具有同步 Data(contentsOf
的远程 URL 加载数据。
var players = [Player]()
let jsonUrl = URL(string: "url.json")!
let task = URLSession.shared.dataTask(with : url) [unowned self] (data, _, error) in
if let error = error print(error); return
do
players = try JSONDecoder().decode([Player].self, from: data!).sorted $0.score < $1.score
DispatchQueue.main.async // reload the table view if necessary
self.tableView.reloadData()
catch print(error)
task.resume()
【讨论】:
感谢 alott @vadian 这对我有很大帮助,很抱歉我是 swift 新手,我正在获取这样的 Json 文件let jsonUrl = URL(string: "url.json") do let data = try Data(contentsOf: jsonUrl!) //let json = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary json = try (JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.mutableContainers) as? NSArray)!
你有什么建议吗?
谢谢@Vadian 我做了完全一样的,但是在打印播放器时它说(CodingKeys in _D02FB714673388A51EFFF7A36D0361B0).score], debugDescription: "Expected to decode Int but found a string/data instead.", underlyingError: nil)
那么Score
的值为String
,在声明行中更改类型:let score : String
,您必须更改排序闭包。我更新了答案。【参考方案2】:
解析完你的json后,你可以像这样对你的分数数组进行排序
var scoreArray = ["500", "0", "2000", "300", "900"]
array.sort $0.compare($1, options: .numeric) == .orderedAscending
【讨论】:
我有 json 数组,我正在使用 - let obj = NSSortDescriptor.init(key: key, ascending: false) 但它没有正确排序。我想根据ID排序。数组 - EastLong = "-75.54663212158209"; NorthLat = "40.07097483544585"; ServiceAreaBroughtBy = "交通产品";服务区启用 = 1;服务区 ID = 1024; ServiceAreaName = "演示交通产品办公室"; SouthLat = "40.0198272706342"; WestLong = "-75.63005399999997"; ,【参考方案3】:我以前做过这样的事情
首先我创建了两个字典数组
var jsonArray = [(name:String, score:String)]()
var sortedscoreArray:[(name: String, score: String)] = []
在获取 json 数据时,您可以创建 for 循环
for I in 0..< jsonData.count
Let jsonInfo = jsonData[i]
jsonArray.append((name: jsonInfo[“Name”].string!, score: jsonInfo[“Score"].string!))
在你填写完 json 数组后,将它传递给 sortedArray
sortedscoreArray = jsonArray.sorted(by: $0.score < $1.score )
【讨论】:
【参考方案4】:如果数组包含字典,那么您可以使用此代码进行排序:
let sortedArray = json.sort $0["Score"] as! Int < $1["Score"] as! Int
print(sortedArray)
如果您使用的是 bean 类,那么您可以使用 dot(.) 属性进行排序:
let sortedArray = json.sort $0.Score < $1.Score
print(sortedArray)
【讨论】:
我没有看到 OP 在哪里使用 SwiftyJSON...我认为他们没有使用它... @Moritz,我已经更新了我的答案,请再次检查。.intValue
是一个 SwiftyJSON getter。我不认为 OP 使用 SwiftyJSON。
如果数组声明为NSArray
,第二个错误依然存在。这是主要问题。【参考方案5】:
let sortedResults = self.json?.sorted(by: $0.name ?? EMPTY_STRING < $1.name ?? EMPTY_STRING ) ?? []
【讨论】:
A code-only answer is not high quality。虽然此代码可能很有用,但您可以通过说明其工作原理、工作方式、何时应该使用以及它的局限性来改进它。请edit您的回答包括解释和相关文档的链接。以上是关于如何在swift 4中对数组中的JSON数据进行排序的主要内容,如果未能解决你的问题,请参考以下文章