swift4如何从JSON中提取值到数组

时间:2018-01-21 01:50:13

标签: json swift

我有一个本地JSON文件,如下所示。如何提取坐标的所有值并存储在数组中?谢谢!

{   
 "type":"FeatureCollection",
 "features":[
    {
    "type":"Feature",
    "geometry":{
     "type":"Point",
     "coordinates":[144.3429008,-38.17437148]
    },
   "properties":{
    "name":"Wilson Road"
   },
  {
   "type":"Feature",
   "geometry":
    {"type":"Point",
    "coordinates":[145.1801783,-37.6602503]
    },"
    properties":{
    "name":"Wilson Road"
   }
  .......

我试过了

 let path = Bundle.main.path(forResource: "json", ofType: "json")
 let jsonData=NSData(contentsOfFile: path!)
    do {
        let parsedData = try JSONSerialization.jsonObject(with: jsonData! as Data, options:[]) as! [String:AnyObject]
        let features = parsedData["features"] as! NSArray
        print(features)
    }catch{}

输出

 ( ......
    {
    geometry =         {
        coordinates =             (
            "144.3429008",
            "-38.17437148"
        );
        type = Point;
    };
    ......

下一步是什么?

3 个答案:

答案 0 :(得分:1)

首先,您的JSON无效JSON。它在键值对后面缺少一个逗号。

至于您的代码,您不应该尝试将JSON Dictionary转换为[String:AnyObject],它应该是[String:Any]。你也不应该在Swift中使用NSArray,在解析JSON字典数组时使用[[String:Any]]

当您立即将其转换为NSData时,您也不应该在Swift中使用Data。首先使用相同的Data初始化程序。

let path = Bundle.main.path(forResource: "json", ofType: "json")
do {
    let jsonData = try Data(contentsOfFile: path!)
    guard let parsedJson = try JSONSerialization.jsonObject(with: jsonData) as? [String:Any] else {return}
    guard let features = parsedJson["features"] as? [[String:Any]] else {return}
    print(features)
} catch {
    print(error)
}

正确的JSON:

let json = """
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [144.3429008, -38.17437148]
},
"properties": {
"name": "Wilson Road"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [145.1801783, -37.6602503]
},
"properties ": {
"name": "Wilson Road"
}
}
]
}
"""

答案 1 :(得分:1)

由于您使用的是Swift 4,因此请使用Decodable。这种方法的优点是它是强类型的。处理动态字典和数组可能会很快变得混乱。

以下数据结构简化为仅包含问题所需的内容。如果您需要,可以添加更多属性:

struct ServerResponse: Decodable {
    var type: String
    var features: [Feature]
}

struct Feature: Decodable {
    var geometry: Geometry
}

struct Geometry: Decodable {
    var coordinates: [CGFloat]
}

用法:

let json = """
{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [144.3429008, -38.17437148]
            },
            "properties": {
                "name": "Wilson Road"
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [145.1801783, -37.6602503]
            },
            "properties ": {
                "name": "Wilson Road"
            }
        }
    ]
}
""".data(using: .utf8)!

var response = try JSONDecoder().decode(ServerResponse.self, from: json)
var coordinates = response.features.map { $0.geometry.coordinates }
// [[144.3429008, -38.17437148], [145.1801783, -37.6602503]]

答案 2 :(得分:0)

您可以遍历数组。

其中array是您要访问的features数组:

let new_array = []
for item in array:
    for coord in item[“coordinates”]:
        new_array.append(coord)

print(new_array)

这应该给你一个输出:

 [144.3429008, -38.17437148, 145.1801783, -37.6602503]

如果你喜欢这样的话:

[[144.3429008, -38.17437148], [145.1801783, -37.6602503]]

您可以直接追加项目[“coordinates”]:

let new_array = []
    for item in array:
        new_array.append(item[“coordinates”])

print(new_array)