Парсинг json ответа сервера в многомерный массив

swift
xcode
ios

#1

Пытаюсь распарсить json ответ сервера в многомерный массив. Но с массивом что то не так и в итое появляется ошибка. Объявляю массив:

                     var catlatlon: [[AnyObject]] = []

Сам цикл присваивания значений:

                     for index in 0...json.count-1 {
                        let aObject = json[index] as! [String : AnyObject]                            
                        self.catlatlon[index][0] = aObject["tp"] as AnyObject
                        self.catlatlon[index][1] = aObject["lt"] as AnyObject
                        self.catlatlon[index][2] = aObject["ln"] as AnyObject
                    }

Дело в том что требуется что бы в массиве содержались и Int и Double и String типы данных.
Если же я объявляю несколько одномерных массивов как String:

var catlatlon1: [String] = []
var catlatlon2: [String] = []
var catlatlon3: [String] = []

и потом присваиваю каждому значение:

                     for index in 0...json.count-1 {
                        let aObject = json[index] as! [String : AnyObject]
                        self.catlatlon1.append(aObject["tp"] as! String)
                        self.catlatlon2.append(aObject["lt"] as! String)
                        self.catlatlon3.append(aObject["ln"] as! String)
                    }

То все присваивается как надо. В чем может быть проблема подскажите.


#2

String не может быть AnyObject String это структура, в смысле конечно может но это как объявить массив баранов и наложить туда овец :slight_smile:
И покажите JSON.


#3

JSON простейший [{“tp”:“5”,“lt”:“52.4567”,“ln”:“54.7896”},{“tp”:“6”,“lt”:“53.4897”,“ln”:“50.79916”}].
Я не могу догнать как пользоваться массивами. Хорошо. Я оставил это место в покое и присваиваю string в разные одномерные массивы. Создаю функцию где буду присваивать этот массив другому массиву многомерному:

var catlatlon: [[Double]] = []


 func massivredefinition(){
      for index in 0...catlatlonType.count-1 {            
          catlatlon[index][0] = Double(catlatlonType[index])!
          catlatlon[index][1] = Double(catlatlonLat[index])!
          catlatlon[index][2] = Double(catlatlonLon[index])!            
      }
 }

Но все равно выходит ошибка.


#4

У вас в json только строки, попробуйте так:

let jsonData = "[{\"tp\":\"5\",\"lt\":\"52.4567\",\"ln\":\"54.7896\"},{\"tp\":\"6\",\"lt\":\"53.4897\",\"ln\":\"50.79916\"}]".data(using: .utf8)!

let array = try! JSONSerialization.jsonObject(with:jsonData) as! [[String: String]]


struct Coordinate {
    let tp: Int
    let lt: Double
    let ln: Double
    
    init(_ dict: [String: String]) {
        tp = Int(dict["tp"]!)!
        lt = Double(dict["lt"]!)!
        ln = Double(dict["ln"]!)!
    }
}

let coordinates = array.map { Coordinate($0) }

print(coordinates)

#5

Мне кажется если я использую Ваш способ я не смогу создать многомерный массив который мне необходимо вызывать в последующем для получения из него данных в различных циклах обращением к нему по индексу типа:

                     coorlat = catlatlon[0][1]
                     coorlon = catlatlon[0][2]

Или я не прав?


#6

Зачем вам двухмерный массив из json (который массив объектов) который преобразуется в массив словарей [[String: String]]?

Из моего способа вы получите массив структур и к структуре в массиве можно обращаться по индексу:

let coordinate = coordinates[0]
coordinate.lt
coordinate.ln

#7

Мне нужен конечный двумерный массив с данными для построения маркеров в цикле. Просто на андроиде это раз два расплюнуть создается массив и происходит обращение к нему по индексам,
Например coor[0][0] - тип маркера, coor [0][1] - широта маркера, coor[0][2] - долгота маркера.
в цикле for я создаю маркеры путем подстановки индекса coor[i][0] итд итп. Неужели нет способа получить просто двумерный массив без всяких заморочек что бы можно было к нему обращаться просто и перебирать его в циклах. И короткую JSON строку я вам привел для примера. Обысно в ней содержаться данные о 100 метках


#8

Можете получить двухмерный массив строк и дальше со строками делать что угодно:

let jsonData = "[{\"tp\":\"5\",\"lt\":\"52.4567\",\"ln\":\"54.7896\"},{\"tp\":\"6\",\"lt\":\"53.4897\",\"ln\":\"50.79916\"}]".data(using: .utf8)!
let jsonArray = try! JSONSerialization.jsonObject(with:jsonData) as! [[String: String]]
let array = jsonArray.map { $0.map { $0.value } }

Возможно на андроид с его jvm и глюками это считается хорошей практикой:

coor[i][0]

Но я бы советовал использовать типизированный массив со структурами:

coordinates[i].lt

#9

Прислушался к вашему совету, сделал так как вы описали, все получилось, все работает, спасибо! Просто не привычно по первой после Java делать по другому)))