斯威夫特字典字典

问题描述:

我想建立一本字典词典。在Swift中,我该如何声明一个带有String键的字典和这个相同类型的字典的值?我需要能够有无限的巢穴。 (有点像建筑物使用节点树除非它不是一棵树,它是一本字典。)斯威夫特字典字典

我试着用AnyObject,却得到了一个转换错误:

var node1: Dictionary<String, AnyObject?> = ["foo" : nil] 
var node2: Dictionary<String, AnyObject?> = ["bar" : node1] // ERROR: Cannot convert value of type 'Dictionary<String, AnyObject?>' (aka 'Dictionary<String, Optional<AnyObject>>') to expected dictionary value type 'Optional<AnyObject>' 

是否有一个类型安全的方法做这个(即不使用AnyObject?)

+2

有多少个字典结束后?还是它是字典一直下降? – overactor

+0

是的,它是无限的。 – Daniel

+1

Surly拥有无限的词典组意味着你永远不会存储任何数据?正如你将密钥的字符串,然后另一个字典作为值。你永远不会存储除键之外的任何东西。我想也许另一个数据结构会更适合。你想达到什么目的? – Welton122

你可以通过使用结构和枚举来实现类似这样的API,并通过swift输入安全类型。

enum RecursiveDictValue<KeyType: Hashable, ValueType> { 
    case Value(ValueType) 
    case Dict(RecursiveDict<KeyType, ValueType>) 
} 

struct RecursiveDict<KeyType: Hashable, ValueType> { 
    typealias OwnType = RecursiveDict<KeyType, ValueType> 

    private var dict: [KeyType: RecursiveDictValue<KeyType, ValueType>] 

    init() { 
     dict = [:] 
    } 

    init(dict: [KeyType: RecursiveDictValue<KeyType, ValueType>]) { 
     self.dict = dict 
    } 

    // this ensures that we can safely chain subscripts 
    subscript(key: KeyType) -> OwnType { 
     get { 
      switch dict[key] { 
      case let .Dict(dict)?: 
       return dict 
      default: 
       return RecursiveDict<KeyType, ValueType>() 
      } 
     } 

     set(newValue) { 
      dict[key] = .Dict(newValue) 
     } 
    } 

    subscript(key: KeyType) -> ValueType? { 
     get { 
      switch dict[key] { 
      case let .Value(value)?: 
       return value 
      default: 
       return nil 
      } 
     } 

     set(newValue) { 
      if let newValue = newValue { 
       dict[key] = RecursiveDictValue<KeyType, ValueType>.Value(newValue) 
      } else { 
       dict[key] = nil 
      } 
     } 
    } 
} 

这个工程相当不错(请注意,你需要帮助迅速与种类虽然):

var dict = RecursiveDict<String, Int>(dict: ["value":.Value(1), 
              "dict":.Dict(RecursiveDict<String, Int>(dict: ["nestedValue": .Value(2)]))]) 

if let value: Int = dict["value"] { 
    print(value) // prints 1 
} 

if let value: Int = dict["dict"]["nestedValue"] { 
    print(value) // prints 2 
} 

当你做的东西是不能工作预期也将失败。

if let value: Int = dict["dict"] { 
    print(value) // is not executed 
} 

if let value: Int = dict["dict"]["nestedDict"]["nestedValue"] { 
    print(value) // is not executed 
} 

而且你可以在嵌套的字典,甚至设定值还没有被创建!:

dict["dict"]["nestedDict2"]["nestedValue"] = 3 


if let value: Int = dict["dict"]["nestedDict2"]["nestedValue"] { 
    print(value) // prints 3 
} 

很少信息..你的意思是无限嵌套字典?我不这么认为..

func returnDict() -> Dictionary<String, AnyObject> { 
     return ["Got You" : returnDict()] 
    } 


var x : Dictionary<String, AnyObject> = ["GotYou" : returnDict()] 

只是说,没有什么更好的可以发生在这个以外崩溃

这是无限递归的情况。当你有无限的词典时,它并不意味着它会永远运行。这意味着它将运行到您的设备内存不足。调用函数returnDict,调用returnDict,它将再次调用returnDict等。

递归基本上是将一个方法添加到内存中预先存在的方法堆栈上。这可能会发生,直到堆栈溢出。因此,计算器

let node1: Dictionary<String, AnyObject!> = ["foo" : nil] 
var node2 = ["bar" : node1] 

游乐场批准它

enter image description here

+0

我需要无限的巢穴。这就是棘手的问题。 – Daniel

+0

为什么你需要无限的巢穴?它会如何帮助你? –

+0

原因我只知道运行时需要多深。 – Daniel

的原因是,在Dictionary类型等在Objective-C值必须是非选。

无论如何,这并不是很有用,因为在Swift中为键分配nil值会删除密钥。

var node1: Dictionary<String, AnyObject> = ["foo" : "Hello"] 
var node2: Dictionary<String, AnyObject> = ["bar" : node1] 

我与火力的工作,我需要实现类似的结构,这一点:

["llave3": ["hola": "", "dos": ""], "llave1": ["hola": "", "dos": ""],  "llave2": ["hola": "", "dos": ""]] 

这是一个嵌套字典或词典的字典。我只是这样做的:

var array = ["llave1", "llave2","llave3"] 
var dictOfDictionarys = [String : [String : String]]() 

for items in array { 
     dictOfDictionarys[items] = ["hola":"","dos":""] 
}