2016-05-30 164 views
-1

我想建立一本字典詞典。在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

回答

4

你可以通過使用結構和枚舉來實現類似這樣的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 
} 
0

很少信息..你的意思是無限嵌套字典?我不這麼認爲..

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

0

的原因是,在Dictionary類型等在Objective-C值必須是非選。

無論如何,這並不是很有用,因爲在Swift中爲鍵分配nil值會刪除密鑰。

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

我與火力的工作,我需要實現類似的結構,這一點:

["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":""] 
}