【问题标题】:How to sort JSON Data in Array in swift 4如何在swift 4中对数组中的JSON数据进行排序
【发布时间】:2026-02-17 07:00:01
【问题描述】:

我有这样的 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 的回答。

标签: swift nsarray nsdictionary swift4


【解决方案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您的回答包括解释和相关文档的链接。
    最近更新 更多