Чтение данных из файла (не JSON) и преобразование в объекты - PullRequest
0 голосов
/ 22 апреля 2019

Я пытаюсь прочитать содержимое файла и преобразовать его в объекты. Содержимое представляет собой массив словарей, но не JSON (ключи не заключены в кавычки). Содержание как ниже

[ {
    id: 13,
    start: "2018-01-12",
    end: "2018-02-16",
    name: "Fourth item with a super long name"
  },
  {
    id: 14,
    start: "2018-02-01",
    end: "2018-02-02",
    name: "Fifth item with a super long name"
  }
]

Я хочу иметь возможность прочитать его и создать массив объектов, структурированных так:

struct TimelineItem: Codable {
    var id: Int
    var start: String
    var end: String
    var name: String
}

Кодируемый способ предпочтителен, но не обязателен.

Я пробовал Google, но мне не повезло.

Ответы [ 2 ]

0 голосов
/ 22 апреля 2019

В комментариях выше вы спросили, есть ли способ конвертировать ваш текст в JSON, чтобы вы могли использовать Codable с ним.

Вот хрупкий способ сделать это.Если не-JSON-файл представляет собой статический файл, связанный с вашим приложением, то это не должно быть проблемой.Если вы получаете эти данные из какого-либо веб-сервиса, не используйте их.

Считайте ваш файл в переменную.(Здесь я укажу это вручную.)

let string = """
[
    {
        id: 13,
        start: "2018-01-12",
        end: "2018-02-16",
        name: "Fourth item with a super long name"
    },
    {
        id: 14,
        start: "2018-02-01",
        end: "2018-02-02",
        name: "Fifth item with a super long name"
    }
]
"""

Regex заменяет пробелы, за которыми следуют слова и двоеточие (например: id:), и заключает их в кавычки.

let json = string.replacingOccurrences(of: "\\s+(\\w+): ", with: "\"$1\": ", options: [.regularExpression])

Это выведет следующую строку:

[
    {
        "id": 13,
        "start": "2018-01-12",
        "end": "2018-02-16",
        "name": "Fourth item with a super long name"
    },
    {
        "id": 14,
        "start": "2018-02-01",
        "end": "2018-02-02",
        "name": "Fifth item with a super long name"
    }
]

После этого вы сможете декодировать строку как JSON, используя кодируемый.

0 голосов
/ 22 апреля 2019

Я бы преобразовал строку not-json в строку json:

let notjson = """
[
{
    id: 13,
    start: "2018-01-12",
    end: "2018-02-16",
    name: "Fourth item with a super long name"
},
{
    id: 14,
    start: "2018-02-01",
    end: "2018-02-02",
    name: "Fifth item with a super long name"
}
]
"""

let pattern = "(\n\\s*)([a-z]*)(:)"
let repl = "$1\"$2\"$3"
let regex = try! NSRegularExpression(pattern: pattern, options: [])
let json = regex.stringByReplacingMatches(in: notjson, options: [], 
    range: NSRange(location: 0, length: notjson.utf16.count), withTemplate: repl)

Хорошо, теперь мы свели это к ранее решенной проблеме, как мы говорим в математике. У нас есть JSON, поэтому мы можем просто расшифровать его:

struct Thing : Decodable {
    let id : Int
    let start : String
    let end : String
    let name : String
}
let things = try! JSONDecoder().decode([Thing].self, from:json.data(using: .utf8)!)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...