在Swift 3中,如何将字典转换为Object?

时间:2017-09-21 01:38:53

标签: swift object dictionary

[我是Swift的新手,我不知道这是否可能,所以请建议我]

我有一本字典(动态),如:

let simpleHash = ["testA": "A", "testB": "B", "testC": "C"]

我想将其转换为Object,以便我可以访问:

simpleHash.testA // instead of simpleHash["testA"]

我已经尝试了下面的一个,但它没有帮助

let jsonData = try JSONSerialization.data(withJSONObject: simpleHash, options: .prettyPrinted)
let decoded = try JSONSerialization.jsonObject(with: jsonData, options: [])

任何人都可以就此提出建议。 提前谢谢!

2 个答案:

答案 0 :(得分:1)

Swift将需要为testA显式声明的变量,因此您将无法100%动态。但是,由于您需要在代码中使用变量,因此在某些时候将会知道它。鉴于此并且本着最小化声明约束的精神,您可以定义一个使用字典作为其内部存储的类,并将键值公开为计算属性。

这是一个例子:

class DictionaryBased
{
   var content:[String:Any]
   init(_ dictionary:[String:Any])
   { content = dictionary }

   func get<T>(_ key:String, _ defaultValue:T) -> T 
   { return content[key] as? T ?? defaultValue }

   func set<T>(_ key:String, _ value:T)  
   { content[key] = value }
}

class SimpleHash:DictionaryBased 
{}

通过这种方式,您可以根据需要(以及需要时)使用扩展名添加计算属性。

extension SimpleHash
{
  var testA:String { get { return get("testA", "") }  set { set("testA",newValue) } }
  var testB:String { get { return get("testB", "") }  set { set("testB",newValue) } }

  // if variables are "read-only", you don't need the set { } part
  var testC:String { get { return get("testC", "") }  }
}

您可以添加是否键入的变量并支持选项,或者(如上所述)提供默认值。

extension SimpleHash
{
  var testD:Any?    { get { return get("testD", nil) }  set { set("testD",newValue) } }
  var testE:String? { get { return get("testE", nil) }  set { set("testE",newValue) } }
  var testF:Date?   { get { return get("testF", nil) }  set { set("testE",newValue) } }
}

使用这个&#34;基于词典&#34;对象,你需要在某个时刻创建一个实例并给它字典的内容:

let simpleHash = SimpleHash(["testA": "A", "testB": "B", "testC": "C"])

simpleHash.testA  // "A"
simpleHash.testD  // nil

请注意,这并不像使用本机属性和将字典映射到每个物理变量一样高效。另一方面,这样的代码要少得多。如果不经常引用变量,则额外的开销可能是简单和灵活性的可接受的权衡。

答案 1 :(得分:0)

一个简单的struct来保存您的Dictionary值:

struct SimpleStruct {
  // properties are Optional since they might not be matched
  let testA: String?
  let testB: String?

  // this one has a default value
  let testC: String

  // init that takes a Dictionary
  init(dictionary: [String:Any]) {
    // set the Optional ones
    self.testA = dictionary["testA"] as? String
    self.testB = dictionary["testB"] as? String

    // set the one with a default
    self.testC = dictionary["testC"] as? String ?? "C"
  }
}

let foo = SimpleStruct(dictionary: ["testA": "A", "testB": "B", "testC": "C"])

// force-unwrapping for brevity
// you should actually test before using
print(foo.testA!) // prints A
print(foo.testB!) // prints B
print(foo.testC)  // prints C