Как сохранить несколько дат в Swift Struct? - PullRequest
0 голосов
/ 30 сентября 2019

Я бы хотел сохранить событие закрытия предыдущих 4 дней в отдельной структуре, чтобы я мог ссылаться на них позже в программе. Как бы вы сохранили закрывающее событие каждые 4 дня после сортировки из JSON API.

Приведенный ниже код отсортировал предыдущие 4 дня, но я не могу понять, как хранить каждый день, чтобы использовать их отдельно

class DailyViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

    let jsonUrlString = "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=MSFT&apikey=demo"

    let urlObj = URL(string: jsonUrlString)

    URLSession.shared.dataTask(with: urlObj!) {(data, response, error) in
        guard let data = data else { return }
        do {
            let forex = try JSONDecoder().decode(Root.self, from: data)

            let sortedKeys = forex.timeSeriesDaily.keys.sorted(by: >)
            let requestedKeys = sortedKeys.prefix(4)
            var requestedPrices = [String:Forex]()
            requestedKeys.forEach{ requestedPrices[$0] = forex.timeSeriesDaily[$0] }
            print(requestedPrices)
            print()
        } catch {
            print(error)
        }

        }.resume()

}

struct Root: Codable {
    let metaData: [String: String]
    let timeSeriesDaily: [String:Forex]

    enum CodingKeys: String, CodingKey {
        case timeSeriesDaily = "Time Series (Daily)"
        case metaData = "Meta Data"
    }
}

struct Forex: Codable {
    let open, high, low, close: String

    enum CodingKeys: String, CodingKey {
        case open = "1. open"
        case high = "2. high"
        case low = "3. low"
        case close = "4. close"


    }
}

}

Ответы [ 2 ]

0 голосов
/ 30 сентября 2019

Я предлагаю создать другую структуру с датой и закрытием ценой

struct CloseData {
    let date, price : String
}

и заполнить ее

do {
    let forex = try JSONDecoder().decode(Root.self, from: data)
    let sortedKeys = forex.timeSeriesDaily.keys.sorted(by: >)
    let requestedKeys = sortedKeys.prefix(4)
    let requestedPrices = requestedKeys.map{ CloseData(date: $0, price: forex.timeSeriesDaily[$0]!.close) }

Результатом является массивCloseData предметов

0 голосов
/ 30 сентября 2019

Один из способов - создать структуру с четырьмя свойствами для этого и добавить конкретную инициализацию, которая принимает массив

struct LastFour {
    var close1: String
    var close2: String
    var close3: String
    var close4: String

    init?(_ closes: [String]) {
        guard closes.count >= 4 else {
            return nil
        }
        close1 = closes[0]
        close2 = closes[1]
        close3 = closes[2]
        close4 = closes[3]
    }
}

, а затем использовать map при инициализации структуры из словаря

let lastFour = LastFour(requestedPrices.values.map {$0.close})

Обратите внимание, что init является необязательным и возвращает nil в случае короткого массива, другой вариант может быть, например, для выдачи ошибки.

Возможно, более гибким решением будет использование массивавнутренне в структуре, а затем доступ к данным через метод или, возможно, вычисленные свойства

struct LastFour {
    private var closeEvents: [String]

    func close(at index: Int) -> String {

    }
}

Это, конечно, потребует аналогичного кода для init и проверки правильного размера, но было бы легче изменить, если больше или меньшенужны элементы

...