简体   繁体   English

在带有数组的枚举“ For循环”的Swift填充字典中处理类型

[英]Handling Types in Swift, Populating Dictionary With Enumeration 'For Loop' Through Array

I am filling a dict with values from json: 我用json的值填充字典:

var dict = Dictionary<String, AnyObject>()

dict["venue"] =         json["info"]["venue"].string!
dict["addressStreet"] = json["info"]["addressStreet"].string!
dict["capacity"] =      json["info"]["capacity"].int!
dict["mascot"] =        json["info"]["mascot"].string!
dict["foodService"] =   json["info"]["foodService"].boolean!

Imagine the values from the json are: 想象一下json中的值是:

//Smith Concert Hall (a string)
//1234 Main Street (a string)
//150 (a number)
//no mascot listed - a null value
//true for food service - a boolean value

In case it has a bearing on this question, I am using SwiftyJSON to access the items in json. 如果它与这个问题有关,我正在使用SwiftyJSON来访问json中的项目。 Info on SwiftyJSON is here: https://github.com/SwiftyJSON/SwiftyJSON 关于SwiftyJSON的信息在这里: https : //github.com/SwiftyJSON/SwiftyJSON

So, in this example we are dealing with several different types, such as strings, ints, booleans, and the chance of null values. 因此,在此示例中,我们处理几种不同的类型,例如字符串,整数,布尔值和空值的机会。

The json I am working on doesn't just have 5 items like in the above example. 我正在处理的json不仅具有上述示例中的5个项。 It has many. 它有很多。 So, for an efficient program, I have done the following: 因此,对于一个高效的程序,我做了以下工作:

for (indexCount, element) in enumerate(appDelegate.json["info"]){
    dict[element.0] = json["info"][element.0]
}

Which means instead of creating specific assignment statements for all possibilities, I am looping through and creating a tuple from each json item. 这意味着我不是在为所有可能的情况创建特定的赋值语句,而是在每个json项中循环并创建一个元组。 The tuple contains the key and value. 元组包含键和值。 With that key and value I am automatically setting the key and value of the dict items. 使用该键和值,我将自动设置字典项的键和值。

BUT - when I go to use the dict item later, there is a problem. 但是-当我稍后使用字典项目时,出现了问题。 For example, if I try to do this, I get nil: 例如,如果我尝试执行此操作,则会得到nil:

let a = dict["capacity"] as? String
println(a)  //results with: nil

let b = dict["capacity"]
println("\(b)")  //results with: nil

let c = String(stringInterpolationSegment: dict["capacity"])
println(c)  //results with: nil

So to recap: If I am filling an "String, AnyObject" dictionary by enumerating through a json array with different value types... what can I do on the front or back end of this process to avoid errors and have useful data? 回顾一下:如果我通过枚举具有不同值类型的json数组来填充“ String,AnyObject”字典,那么在该过程的前端或后端该怎么做以避免出错并获得有用的数据? In particular, strings seem to work fine, but when I encounter an int and try to cast it as a string (I have tried several ways) it fails all together or returns nil. 特别是,字符串似乎可以正常工作,但是当我遇到一个int并尝试将其转换为字符串时(我尝试了几种方法),它会全部失败或返回nil。

Thank you. 谢谢。

The data held in a JSON object can be String , Bool , NSNumber , NSURL , ... and you are using only String , Int and Bool . JSON对象中保存的数据可以是StringBoolNSNumberNSURL ,...,并且您仅使用StringIntBool The common supertype of these is Any . 这些的常见超类型是Any Declare your dict as Dictionary<String,Any> . 将您的dict声明为Dictionary<String,Any> (Every where you subsequently use your Any data you will be forced to type-cast to String , Bool , Int as appropriate for the 'tag') (在随后使用“ Any数据的Any都将被强制类型转换为适用于“标签”的StringBoolInt

But, I'd say, by using Any you are fighting the types. 但是,我想说的是,通过使用Any您可以与各种类型作斗争。 Swift is a strongly-typed, statically-typed programming language and you need to go with it by being explicit with your types. Swift是一种强类型的,静态类型的编程语言,您需要通过明确使用类型来使用它。 Get your generic input data, from JSON, into explicitly-typed abstractions, manipulate those abstractions, and then, if required, convert back to generic output data, to JSON. 将来自JSON的通用输入数据转换成显式类型的抽象,处理这些抽象,然后根据需要将其转换回通用输出数据,再转换为JSON。

class Event {
  var venue : String
  var addressStreet : String
  var capacity : Int
  var mascot : String
  var foodService : Bool
  // ... many more ...

  init (json:JSON) {
    self.venue = json["venue"].string!
    ...
  }
}

var event1 = Event(json["info"])

Of course, the above only works if the JSON data tags are static. 当然,以上内容仅在JSON数据标签为静态的情况下有效。 If, rather, there really is no static structure to the data, then Dictionary<String,Any> is the best you can do and you'll need to deal with Any . 相反,如果确实没有数据的静态结构,则Dictionary<String,Any>是您可以做的最好的事情,您将需要处理Any

It turns out, when looping through JSON to add the items to a dictionary, you don't need to worry about their type. 事实证明,当遍历JSON将项目添加到字典中时,您不必担心它们的类型。 You can just add them just as they are: unchanged in their 'JSON' type to the array. 您可以按原样添加它们:将其“ JSON”类型保留不变。

This question began with a loop through JSON results to add them to a dictionary: 这个问题首先循环遍历JSON结果以将它们添加到字典中:

var dict = Dictionary<String, AnyObject>()
for (indexCount, element) in enumerate(appDelegate.json["info"]){
    dict[element.0] = json["info"][element.0]
}

Now I see that the problem was that the array was defined as 'String, AnyObject'. 现在,我看到问题是该数组定义为“ String,AnyObject”。 But it turns out if we declare the array as: 但是事实证明,如果我们将数组声明为:

var dict = Dictionary<String, JSON>()

(we changed AnyObject to JSON)...then we are able to add and retrieve the original JSON value. (我们将AnyObject更改为JSON)...然后,我们可以添加和检索原始JSON值。 Then when we are about to use the value somewhere (such as putting string into a label, or getting an int to do a calculation) SwiftyJSON allows us to cast it with a subscript such as .string or .int. 然后,当我们要在某个地方使用该值时(例如,将字符串放入标签中,或让int进行计算),SwiftyJSON允许我们使用下标(例如.string或.int)来强制转换它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM