如何在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,它只是 NSDictionaryNSArray。正如@Larme 提到的,如果可以的话,你应该避免使用这些人,使用原生 Swift 集合(例如[[String: Int]])。 看起来您忘记将字典转换为对象(使用结构或类),这将极大地帮助管理这些数据。您应该避免直接使用 JSON 和字典,最好使用模型对象。 对不起,我对 swift 很陌生,我不知道该怎么做.. @FaizyZaidy 看看 vadian 的回答。 【参考方案1】:

这是一个很好的例子,为什么强烈建议您不要在 Swift 中使用 NSArrayNSDictionary

两种集合类型都不提供类型信息,因此所有内容都被视为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数据进行排序的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中对对象数组进行排序?

如何在 Swift 5 中对数组的数组进行排序 [关闭]

我如何使用解码器在swift 4中解析tableview中的json数组

如何在 Swift 中对 NSDate 进行排序

如何在颤动中对对象列表中的json字符串进行编码

在 Swift 中对协议数组进行排序?