2017-01-07 36 views
9

爲了渲染鬍鬚模板而將數據有效載荷傳遞到GRMustache.swift,我處於需要將數據追加到之前在字典中定義的數組的場景。在[String:Any]字典結構中追加到數組

我的數據結構開始瞭如:

var data: [String: Any] = [ 
    "key1": "example value 1", 
    "key2": "example value 2", 
    "items": [ 
     // I need to append here later 
    ] 
] 

items密鑰對的集合,我需要一個循環內後追加。

爲了增加data["items"]陣列,我想是這樣的:

for index in 1...3 { 
    let item: [String: Any] = [ 
     "key": "new value" 
    ] 

    data["items"].append(item) 
} 

這個錯誤,Any?類型的值沒有成員append,和二元運算+=不能應用於Any?類型的操作數和[String : Any]

這是有道理的,因爲我需要將值追加;然而,我不能改變數組。

鑄造到陣列中,是否迫使垂頭喪氣給出了錯誤:

(data["items"] as! Array).append(item) 

'Any?' is not convertible to 'Array<_>'; did you mean to use 'as!' to force downcast?

Cannot use mutating member on immutable value of type 'Array<_>'

好像我的演員是錯誤的;或者,也許我會以錯誤的方式解決這個問題。

任何有關如何隨着時間的推移迭代填寫data["items"]的建議?

回答

6

data[Items]的類型不是Array而是實際上Array<[String: Any]>

你也許可以擠進這個成更少的步驟,但我更喜歡的多個步驟清晰:

var data: [String: Any] = [ 
    "key1": "example value 1", 
    "key2": "example value 2", 
    "items": [] 
] 

for index in 1...3 { 

    let item: [String: Any] = [ 
     "key": "new value" 
    ] 

    // get existing items, or create new array if doesn't exist 
    var existingItems = data["items"] as? [[String: Any]] ?? [[String: Any]]() 

    // append the item 
    existingItems.append(item) 

    // replace back into `data` 
    data["items"] = existingItems 
} 
3

subscriptDictionary總是返回optional(?)實例,因爲它可能可能key沒有在Dictionary存在。現在你已經聲明你的字典爲[String:Any]意味着key的類型是StringvalueAny

現在當你寫data["item"]它會返回你Any?這不是陣列,所以你不能調用append它會返回不可變的值,所以你不能直接改變它。

因此,您需要將其轉換爲字典數組並將其存儲到實例,然後在使用重新分配字典替換字典中的該對象之後附加該實例。

for index in 1...3 { 
    let item: [String: Any] = [ 
     "key": "new value" 
    ] 

    var array = data["items"] as? [[String:Any]] ?? [[String:Any]]() 
    array.append(item) 
    data["items"] = array 
} 

現在的事情是得到了,如果你有像Dictionary[String: [[String:Any]]]如容易得多。

var data: [String: [[String:Any]]] = [ 
    "items": [] 
] 

for index in 1...3 { 
    let item: [String: Any] = [ 
     "key": "new value" 
    ] 
    data["items"]?.append(item) 
} 
+0

@JasonSturges我知道,我剛纔告訴你什麼是問題,在那裏你可以直接追加字典內的數組。 –

+1

真的很感謝'[String:[[String:Any]]]的輸入的清晰度和優雅。 –

+0

請注意,您可以使用'data [「items」] ?. append(item)'而不是'data [「items」]!。append(item)''above;如果碰巧沒有''items''鍵的值(即使我們知道它在這個例子中),後者會產生運行時崩潰,而前者將簡單地返回一個未使用的'nil'。即使我們知道「項目」鍵存在,我相信我們應該更喜歡安全的方法,特別是當它沒有額外成本時。對於初學者來說,總是有一種加強壞習慣的風險,那麼在這種特殊情況下,例如'!'是安全的,否則通常不會。 – dfri

3

如果願意在清晰度簡潔起見,可以在一個單一的線執行該操作,利用所述nil的聚結操作者和the + operator for RangeReplaceableCollection(向其Array符合),用於後者的「追加」步驟(實際上是在替換data["items"]的價值時構建一個新的集合,以取代現有的集合)。

// example setup 
var data: [String: Any] = [ 
    "key1": "example value 1", 
    "key2": "example value 2", 
    "items": [] 
] 

// copy-mutate-replace the "items" array inline, adding a new dictionary 
data["items"] = (data["items"] as? [[String: Any]] ?? []) + [["key": "new value"]] 

print(data) 
/* ["key2": "example value 2", 
    "items": [["key": "new value"]], 
    "key1": "example value 1"]  */ 

// add another dictionary to the "items" array 
data["items"] = (data["items"] as? [[String: Any]] ?? []) + [["key": "new value"]] 

print(data) 
/* ["key2": "example value 2", 
"items": [["key": "new value"], ["key": "new value"]], 
"key1": "example value 1"]  */ 
0

給你有Arrayitems:[String]

他也可以將它添加到JSON

var items = ["string1", "Info 2","Text 4"] 

data["items"] = items