2017-01-07 5 views
9

मूंछ टेम्पलेट्स को प्रस्तुत करने के लिए GRMustache.swift पर पास किए गए डेटा पेलोड को इकट्ठा करना, मैं एक ऐसे परिदृश्य में हूं जहां मुझे शब्दकोश में परिभाषित एरे में डेटा जोड़ने की आवश्यकता है।सरणी में शामिल करें [स्ट्रिंग: कोई भी] शब्दकोश संरचना

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? की ऑपरेंड के लिए लागू नहीं किया जा सकता के रूप में प्रकार Any? का मूल्य कोई भी सदस्य append, और बाइनरी ऑपरेटर है और [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(?) उदाहरण लौट क्योंकि यह संभव है कि keyDictionary में मौजूद नहीं है हो सकता है। अब आपने अपना शब्दकोश [String:Any] के रूप में घोषित किया है जिसका अर्थ है keyString और valueAny है।

अब जब आप 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

वास्तव में '[स्ट्रिंग: [[स्ट्रिंग: कोई भी]]] टाइपिंग की स्पष्टता, और लालित्य की सराहना करते हैं। –

+0

ध्यान दें कि आप 'डेटा [" आइटम "] का उपयोग कर सकते हैं? डेटा (" आइटम "] के बजाय संलग्न करें (आइटम) '! ऊपर (आइटम) ऊपर जोड़ें; उत्तरार्द्ध एक रनटाइम दुर्घटना उत्पन्न करेगा यदि आइटम "कुंजी" के लिए कोई मूल्य नहीं होता है (भले ही हम इसे इस उदाहरण में जानते हों), जबकि पूर्व बस एक अप्रयुक्त 'शून्य' वापस कर देगा। यहां तक ​​कि यदि हम मौजूद वस्तुओं की कुंजी को जानते हैं, तो भी मुझे विश्वास है कि हमें सुरक्षित दृष्टिकोण पसंद करना चाहिए, खासकर जब यह बिना किसी अतिरिक्त लागत के आती है। हमेशा शुरुआती एसओ पाठकों के लिए खराब '!' अभ्यास को मजबूत करने का जोखिम जो यह नहीं समझता कि इस विशेष मामले/उदाहरण में, '!' सुरक्षित है, लेकिन अन्यथा, आमतौर पर नहीं है। सुझाव के लिए – dfri

3

आप स्पष्टता से अधिक संक्षिप्तता चाहें, तो आप ऑपरेटर और the + operator for RangeReplaceableCollection, (जो Array अनुरूप करने के लिए) बाद के लिए प्रयोग किया जाता है "जोड़ना" कदम वालों nil का इस्तेमाल कर रही (एक पंक्ति में यह कार्रवाई कर सकते हैं, वास्तव में एक नया संग्रह तैयार करना जो 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

दें कि आप एक Array की items:[String]

उन्होंने इस json को

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

data["items"] = items 
संबंधित मुद्दे