#arrays #json #swift #dictionary #parsing
Вопрос:
У меня есть код, который позволяет мне анализировать вложенный файл JSON. Результат декодирования дает мне словарь, как показано ниже, который состоит из строки и объекта, содержащего 5 элементов. Я пытаюсь сопоставить словарь с массивом типа [(Дата,двойной)] с помощью приведенного ниже кода, но это не удается. Xcode подчеркивает знак = и заявляет: «тип выражения неоднозначен без дополнительного контекста». Я не знаю, почему. Любая помощь, помогающая мне понять мою ошибку, будет оценена по достоинству.
var timeSeriesData: [(Date, Double)] = []
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let data = try Data(contentsOf: url) // Works
let decoded = try decoder.decode(VOOSeries.self, from: data) // Works
print(decoded.timeSeries) // produces the following:
[
"2014-09-17":
Stocks.VOOValues(open: "184.1100", high: "184.9200", low: "183.2000",
close: "184.0800", volume: "975000"),
"2016-10-25":
Stocks.VOOValues(open: "197.1300", high: "197.3900", low: "196.4800",
close: "196.7100", volume: "1464904")
]
self.timeSeriesData = decoded.timeSeries.map {
( dateFormatter.date(from: $0.key)!, Double($0.value.close) )
}.sorted { $0.0 < $1.0 } // Xcode does not like the assignment i.e. =
Комментарии:
1. Одно предложение для того, когда вы расшифровываете свои данные. Вы можете декодировать прямо в дату, а не в строку, используя developer.apple.com/documentation/foundation/jsondecoder/. … Это должно устранить двусмысленность.
2. проблема в
Double($0.value.close)
том , что он возвращает необязательное значение. Попробуйте что-нибудь вроде этого:Double($0.value.close) ?? 0.0
3. Возможно, лучшим решением было бы сделать дату свойством в значениях VOO, преобразовать и назначить ее во время декодирования, тогда вам не нужно было бы использовать массив кортежей
4. Спасибо. Добавление ?? 0.0 сработало. Я сделал преобразование во время декодирования, но просто играю с разными подходами. Apple .datedecodingстратегия действительно выглядит интересно. Попробую сделать это в следующий раз.