ios - 按日期发布 tableview 数据的排序顺序 | 迅速
问题描述
本质上,我有一个使用 JSON 数据填充的 tableview,tableview 包含使用 JSON 对数据进行分组的部分allowdate
。
allowdate
如下所示,它包含一个日期,但不是数字格式,而是看起来像:March 26th 2020
所以很难控制它在 tableview 中显示的顺序。
在fetchJSON
我做的功能中:
self.structure.sort { $1. allowdate < $0.allowdate }
但这不能正常工作,并且无法将例如 1 月的日期放在 3 月的日期之上。
var sections = [TableSection]()
var structure = [TableStructure]()
private func fetchJSON() {
guard let url = URL(string: "\(URL.url)example"),
let value = name.addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed)
else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = "item1=\(value)&item2=\(value)".data(using: .utf8)
URLSession.shared.dataTask(with: request) { data, _, error in
guard let data = data else { return }
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
self.structure.sort { $1. allowdate < $0.allowdate }
let res = try decoder.decode([TableStructure].self, from: data)
let grouped = Dictionary(grouping: res, by: { $0. allowdate })
let keys = grouped.keys.sorted()
self.sections = keys.map({TableSection(date: $0, items: grouped[$0]!)})
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
catch {
print(error)
}
}.resume()
}
JSON:
[
{
"person": "Jack",
"allowdate": "March 26th 2020",
"ready_time": "10:00 am"
}
]
要解码此 JSON,我使用以下结构:
struct TableSections {
let date : String
var items : [TableStructure]
}
struct TableStructure: Decodable {
let person: String
let allowdate: String
let ready_time: String
enum CodingKeys : String, CodingKey {
case person, allowdate, ready_time
}
}
解决方案
我在操场上试过这个。它似乎适用于不同的序数:
import UIKit
let json = """
[
{
"person": "Jack",
"allowdate": "March 26th 2020",
"ready_time": "10:00 am"
},
{
"person": "Jill",
"allowdate": "January 1st 2020",
"ready_time": "1:00 pm"
},
{
"person": "Don",
"allowdate": "January 10th 2020",
"ready_time": "1:25 pm"
}
]
"""
struct TableStructure: Decodable {
// These first three come frm the json
let person: String
let allowdate: String
let readyTime: String
// We'll calculate this one later
let compareDate: Date
// This date formatter will read in dates like "January 10th 2020"
// So to use this, we will need to pull the ordinal letters off first
static let dateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM dd yyyy"
return dateFormatter
}()
enum DecodeError: Error {
case compareDateError
}
enum CodingKeys: String, CodingKey {
case person
case allowdate
case readyTime
}
// We decode the three key/values that are passed down, and we calculate a date that we can use to compare
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
person = try values.decode(String.self, forKey: .person)
readyTime = try values.decode(String.self, forKey: .readyTime)
allowdate = try values.decode(String.self, forKey: .allowdate)
if let date = TableStructure.comparingDate(from: allowdate) {
compareDate = date
} else {
throw DecodeError.compareDateError
}
}
// We pull the ordinal letters off of the date, and are left with something cleaner
// A regex could make this much simpler, but me and regex's, we don't get along so great
static func comparingDate(from dateString: String) -> Date? {
var datePurgedArray = dateString.split(separator: " ")
if datePurgedArray.count == 3 {
datePurgedArray[1] = datePurgedArray[1].filter("0123456789.".contains)
let newDateString = datePurgedArray.joined(separator:" ")
print(newDateString)
return TableStructure.dateFormatter.date(from: newDateString)
} else {
return nil
}
}
}
if let jsonData = json.data(using: .utf8) {
print("json Data is \(jsonData)")
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let array = try decoder.decode([TableStructure].self, from: jsonData).sorted { $0.compareDate < $1.compareDate }
print("array is \(array)")
} catch {
print(error.localizedDescription + "could not decode array")
}
} else {
print("could not get data from json")
}
推荐阅读
- .net - .NET 框架?还是 .NET 核心?还是 .NET 标准?或者以上都不是?
- android - 如何使用子数组对主数组进行排序(Android)
- android - Android Intent:如何从浏览器开关取回数据
- windows - 将我的根目录在 GitHub 中上移一级?
- java - 主命令行参数是存储在堆栈内存还是堆内存中?
- javascript - 为什么我的 addeventlistener 只能在一个按钮中工作?
- python - 我想迭代地更新熊猫数据框
- javascript - Clearing an array content and reactivity issues using Vue.js
- python - Python使用正则表达式匹配具有多个换行符的段落
- swift - 如何在我的使用 AVSpeechSynthesizer 播放播放列表的应用程序中修复这个非常复杂的错误?