按 JSON 数组对表视图进行分组

Group tableview by JSON array

我正在使用 swiftyJson 获取一些数据,一切都很好,我得到了一个这样的数组 ("horario_emp"):

[
  {
    "dia" : 1,
    "itinerario" : 0,
    "id_horarios" : 13,
    "jornada" : "05:00:00 - 12:30:00",
    "id_empresa" : 1
  },
  {
    "dia" : 1,
    "itinerario" : 1,
    "id_horarios" : 11,
    "jornada" : "12:00:00 - 19:00:00",
    "id_empresa" : 1
  },
  {
    "dia" : 2,
    "itinerario" : 0,
    "id_horarios" : 14,
    "jornada" : "05:00:00 - 12:30:00",
    "id_empresa" : 1
  },
  {
    "dia" : 2,
    "itinerario" : 1,
    "id_horarios" : 15,
    "jornada" : "12:00:00 - 19:00:00",
    "id_empresa" : 1
  },
  {
    "dia" : 4,
    "itinerario" : 0,
    "id_horarios" : 10,
    "jornada" : "05:00:00 - 12:30:00",
    "id_empresa" : 1
  },
  {
    "dia" : 4,
    "itinerario" : 1,
    "id_horarios" : 12,
    "jornada" : "12:00:00 - 19:00:00",
    "id_empresa" : 1
  }
]

我想知道如何按 "dia" 对数组进行分组?因为我想像这样将数据显示到 tableviewcell 中:

直径 1 乔纳达 05:00:00 - 12:30:00 - 12:00:00 - 19:00:00

直径 2 乔纳达 05:00:00 - 12:30:00 - 12:00:00 - 19:00:00

直径 4 乔纳达 05:00:00 - 12:30:00 - 12:00:00 - 19:00:00

这是我的代码:

class Horarios: NSObject{
    var dia: Int?
    var jornada: [String]?
}

我的控制器:

let horarios = Horarios()
var obj_horarios: [Horarios] = []
let res = JSON(data)
let status = res["status"].boolValue
if(status){
   let info_empresa = res["data"]["empresas"]
   for(_, sub_res):(String, JSON) in info_empresa{
      let horario_emp = sub_res["horario"]
      let allKeys = Set<String>(horario_emp.filter({!([=13=]["dia"].string?.isEmpty)!}).map{[=13=]["dia"].stringValue})
                for key in allKeys {
                    var horarios = Horarios()
                    obj_horarios = horario_emp.filter({
                        [=13=]["dia"].string ?? "" == key
                    }).map({ (json) -> Horarios in
                        horarios.dia = json["dia"].intValue
                        horarios.jornada.append(json["jornada"].stringValue)
                        return horarios
                    })
                }
   }
   self.tableView.reloadData()
}

我收到此错误 Value of tuple type 'JSON.Element' (aka '(String, JSON)') has no member 'subscript' in the line let allKeys.... 我该如何分组?

这个答案不包括使用 SwiftyJSON,而是使用 Swift 4 中的原生 JSON 解析和 Codable 协议.我确信使用 SwiftyJSON 很棒,但是 JSON 的新本地处理使这个任务相当简单:

// jsonText is a String that contains the JSON text
let jsonText = "" // fill in the appropriate text

import Foundation

// the struct to decode into (called Foo for lack of a better name)
struct Foo : Codable {
  let dia: Int
  let itinerario: Int
  let id_horarios: Int
  let jornada: String
  let id_empresa: Int
}

struct Horarios {
  let dia: Int
  let jornada: [String]
}

// push it into a Data and decode it
if let data = jsonText.data(using: .utf8),
  let decoded = try? JSONDecoder().decode([Foo].self, from: data) {

  let obj_horarios =
    // group the Foo objects by the `dia` property as keys,
    Dictionary(grouping: decoded, by: { [=10=].dia })
      // convert the Foo objects into an array of `Horarios` structs
      .map { Horarios(dia: [=10=].0, jornada: [=10=].1.map { [=10=].jornada }) }
      // sort them by `dia`
      .sorted { [=10=].dia < .dia }

  print(obj_horarios)
  // result:
  // [Horarios(dia: 1, jornada: ["05:00:00 - 12:30:00", "12:00:00 - 19:00:00"]),
  //  Horarios(dia: 2, jornada: ["05:00:00 - 12:30:00", "12:00:00 - 19:00:00"]),
  //  Horarios(dia: 4, jornada: ["05:00:00 - 12:30:00", "12:00:00 - 19:00:00"])]
}

此外,如果您只关心键 diajornada,那么您可以简化 Foo struct 以仅包含这些属性:

struct Foo : Codable {
  let dia: Int
  let jornada: String
}

JSON 中的任何附加密钥在解码过程中都将被忽略。

    Define class 

    class Horaios {
        var dia:Int?
        var itinerario:Int?
        var id_horarios:Int?
        var jornada:String?
        var id_empresa:Int?
    }

    implement Sequence extension


    public extension Sequence {
        func categorise<U : Hashable>(_ key: (Iterator.Element) -> U) -> [U:[Iterator.Element]] {
            var dict: [U:[Iterator.Element]] = [:]
            for el in self {
                let key = key(el)
                if case nil = dict[key]?.append(el) { dict[key] = [el] }
            }
            return dict
        }
    }

Call Below method and Output will be like this

dia 1 jordano 05:00:00 - 12:30:00 - 12:00:00 - 19:00:00
dia 2 jordano 05:00:00 - 12:30:00 - 12:00:00 - 19:00:00
dia 4 jordano 05:00:00 - 12:30:00 - 12:00:00 - 19:00:00

    func parseJSON(jsonString:String) {
    let jsonData = jsonString.data(using: String.Encoding.utf8)

        //let groupedItems:[Int:[Horaios]?]?

        do {

            if let data = jsonData {
                let parsedJSON = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableLeaves)

                if let arr = parsedJSON as? [Any] {
                    var items = [Horaios]()
                    for item in arr {
                        if let dict = item as? [String:Any?] {
                            let obj = Horaios()
                            obj.dia = dict["dia"] as? Int
                            obj.itinerario = dict["itinerario"] as? Int
                            obj.id_horarios = dict["id_horarios"] as? Int
                            obj.jornada = dict["jornada"] as? String
                            obj.id_empresa = dict["id_empresa"] as? Int
                            items.append(obj)
                        }
                    }

                    items.sort(by: { (obj1, obj2) -> Bool in
                        if let x = obj1.dia, let y = obj2.dia {
                            return x < y
                        }
                        return false
                    })

                    let groups = items.categorise {[=10=].dia!}

                    let sorted = groups.sorted(by: { (x, y) -> Bool in
                        return x.key < y.key
                    })
                    for xx in sorted {
                        if let componets = groups[xx.key] {
                            var strings = [String]()
                            for x in componets {
                                if let ss = x.jornada {
                                    strings.append(ss)
                                }
                            }
                            print("dia \(xx.key) jordano \(strings.joined(separator:" - "))")
                        }
                    }


                }

            }
        }
        catch {

        }
    }