斯威夫特如何"排序" JSON的字典以时间序列绘制它?

时间:2018-01-21 08:02:33

标签: json swift sorting dictionary

是的,我知道排序字典没有意义,字典根据定义没有排序。

但是我需要对密钥(日期)进行排序,以便我可以用它在图中绘制它(就像最近30天的股票价格图一样)

我目前在这里尝试了2种方法:How do you sort dates in a dictionary?

然而,他们并没有为我工作。

任何人都可以告诉我在这种情况下应该做些什么,这样我就可以在我的情节中得到x轴来按顺序绘制日期(而不是" 2018-01-12"" 2017-12-30"" 2018-1-20")?

这是我的代码

func pastThirtyDaysData(money: String) {    
   Alamofire.request("https://api.coindesk.com/v1/bpi/historical/close.json?currency=\(money)").responseJSON{ (dataFromAPI) in
      if dataFromAPI.result.value != nil {
         let myJSON = JSON(dataFromAPI.result.value)["bpi"].dictionaryObject
         print(myJSON!)
      }
   }
} 

我不知道我应该在这里做什么来按日期排序我的字典键,以便我可以使用该数据在我的情节中绘制它

感谢您的帮助和想法

这里是JSON输出:

{
  "bpi": {
"2017-12-21": 15561.05,
"2017-12-22": 13857.145,
"2017-12-23": 14548.71,
"2017-12-24": 13975.4363,
"2017-12-25": 13917.0275,
"2017-12-26": 15745.2575,
"2017-12-27": 15378.285,
"2017-12-28": 14428.76,
"2017-12-29": 14427.87,
"2017-12-30": 12629.8138,
"2017-12-31": 13860.1363,
"2018-01-01": 13412.44,
"2018-01-02": 14740.7563,
"2018-01-03": 15134.6513,
"2018-01-04": 15155.2263,
"2018-01-05": 16937.1738,
"2018-01-06": 17135.8363,
"2018-01-07": 16178.495,
"2018-01-08": 14970.3575,
"2018-01-09": 14439.4738,
"2018-01-10": 14890.7225,
"2018-01-11": 13287.26,
"2018-01-12": 13812.715,
"2018-01-13": 14188.785,
"2018-01-14": 13619.0288,
"2018-01-15": 13585.9013,
"2018-01-16": 11348.02,
"2018-01-17": 11141.2488,
"2018-01-18": 11250.6475,
"2018-01-19": 11514.925,
"2018-01-20": 12759.6413
  },
  "disclaimer": "This data was produced from the CoinDesk Bitcoin Price Index. BPI value data returned as USD.",
  "time": {
"updated": "Jan 21, 2018 00:03:00 UTC",
"updatedISO": "2018-01-21T00:03:00+00:00"
  }
}

这是我的控制台输出:

["2018-01-19": 11514.925, "2018-01-13": 14188.785, "2017-12-22": 13857.145, "2018-01-02": 14740.7563, "2017-12-29": 14427.87, "2018-01-10": 14890.7225, "2017-12-21": 15561.05, "2018-01-16": 11348.02, "2018-01-17": 11141.2488, "2018-01-03": 15134.6513, "2018-01-15": 13585.9013, "2017-12-31": 13860.1363, "2017-12-30": 12629.8138, "2017-12-27": 15378.285, "2018-01-12": 13812.715, "2017-12-23": 14548.71, "2018-01-05": 16937.1738, "2018-01-18": 11250.6475, "2017-12-25": 13917.0275, "2017-12-28": 14428.76, "2018-01-04": 15155.2263, "2018-01-11": 13287.26, "2018-01-08": 14970.3575, "2018-01-14": 13619.0288, "2017-12-24": 13975.4363, "2018-01-20": 12759.6413, "2018-01-06": 17135.8363, "2018-01-09": 14439.4738, "2018-01-01": 13412.44, "2018-01-07": 16178.495, "2017-12-26": 15745.2575]

3 个答案:

答案 0 :(得分:1)

正如我在评论中提到的 - 您可以使用dict.keys将字典中的所有键放入数组中并对日期进行排序。然后只需使用索引访问它。

guard let dict = myJSON else{ return }

let arrayOfDateStrings = Array(dict.keys).sorted{$0 > $1}

print(dict[arrayOfDateString[indexPath.row]]) // If you want to access data inside tableView

如果日期格式不同,可以使用dateFormatter:

var arrayOfDates: [Date] = []

var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"

for dateString in arrayOfDateStrings {
    let date = dateFormatter.date(from: dateString)
    if let date = date{
        arrayOfDates.append(date)
    }
}


arrayOfDates.sort(by: {$0.timeIntervalSince1970 > $1.timeIntervalSince1970})

var result: [String] = []

for date in arrayOfDates{
    result.append(dateFormatter.string(from: date))
}

print(dict[result[indexPath.row]]) // If you want to access data inside tableView

答案 1 :(得分:0)

您可以在这里使用sort func

let sortedKeys = dict.sorted(by: <)

代码工作

let dict = [
    "2017-12-21": 15561.05,
"2017-12-22": 13857.145,
"2017-12-23": 14548.71,
"2017-12-24": 13975.4363,
"2017-12-25": 13917.0275,
"2017-12-26": 15745.2575,
"2017-12-27": 15378.285,
"2017-12-28": 14428.76,
"2017-12-29": 14427.87,
"2017-12-30": 12629.8138,
"2017-12-31": 13860.1363,
"2018-01-01": 13412.44
  ]

print("-----before sort--------")
for item in dict{
    print(item)
}

let sortedKeys = dict.sorted(by: <) 

print("\n -----After sort--------")
for item in sortedKeys{
    print(item)
}

<强>输出

enter image description here

答案 2 :(得分:0)

我没有使用Alamofire,但独立于此,最好的方法是将字典转换为自定义结构的数组。

这是Swift 4中使用Codable

的示例
let jsonString = """
{"bpi":{"2017-12-21":15561.05,"2017-12-22":13857.145,"2017-12-23":14548.71,"2017-12-24":13975.4363,"2017-12-25":13917.0275,"2017-12-26":15745.2575,"2017-12-27":15378.285,"2017-12-28":14428.76,"2017-12-29":14427.87,"2017-12-30":12629.8138,"2017-12-31":13860.1363,"2018-01-01":13412.44,"2018-01-02":14740.7563,"2018-01-03":15134.6513,"2018-01-04":15155.2263,"2018-01-05":16937.1738,"2018-01-06":17135.8363,"2018-01-07":16178.495,"2018-01-08":14970.3575,"2018-01-09":14439.4738,"2018-01-10":14890.7225,"2018-01-11":13287.26,"2018-01-12":13812.715,"2018-01-13":14188.785,"2018-01-14":13619.0288,"2018-01-15":13585.9013,"2018-01-16":11348.02,"2018-01-17":11141.2488,"2018-01-18":11250.6475,"2018-01-19":11514.925,"2018-01-20":12759.6413},"disclaimer":"This data was produced from the CoinDesk Bitcoin Price Index. BPI value data returned as USD.","time":{"updated":"Jan 21, 2018 00:03:00 UTC","updatedISO":"2018-01-21T00:03:00+00:00"}}
"""
struct Root: Decodable {
    var data = [Historical]()

    let dateFormatter : DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        return formatter
    }()

    private enum CodingKeys : String, CodingKey { case bpi }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let bpi = try container.decode([String:Double].self, forKey: .bpi)
        for (key, value) in bpi {
            data.append(Historical(date: dateFormatter.date(from: key)!, value: value)))
        }
    }
}

struct Historical {
    let date : Date
    let value : Double
}
do {
    let data : Data(jsonString.utf8)
    let result = try JSONDecoder().decode(Root.self, from: data)
    print(result)
} catch {
    print("error: ", error)
}

现在您可以轻松地对Historical数组进行排序。

print(result.data.sorted{ $0.date < $1.date })