मैं स्विफ्ट में एक शब्दकोश से एक विशिष्ट सूचकांक में कुंजी कैसे प्राप्त करूं?


114

मेरे पास एक Dictionaryस्विफ्ट है और मैं एक विशिष्ट सूचकांक पर एक कुंजी प्राप्त करना चाहूंगा।

var myDict : Dictionary<String,MyClass> = Dictionary<String,MyClass>()

मुझे पता है कि मैं चाबियों पर पुनरावृति कर सकता हूं और उन्हें लॉग कर सकता हूं

for key in myDict.keys{

    NSLog("key = \(key)")

}

हालांकि, अजीब तरह से, ऐसा कुछ संभव नहीं है

var key : String = myDict.keys[0]

क्यों ?


11
जैसा कि आप जानते हैं, स्विफ्ट शब्दकोश किसी भी विशिष्ट क्रम में होने की गारंटी नहीं है। तो आप यह सुनिश्चित करने के लिए उम्मीद नहीं कर सकते हैं कि आपके द्वारा लगाए गए क्रम में कुंजी को अनुक्रमित किया जाए।
radex

+1 @ ब्रैडेक्स और भी जोड़ना चाहते हैं, यदि संभव हो तो, आपके बयान के बारे में अधिक पढ़ने के लिए एक स्रोत की बहुत सराहना की जाएगी।
SH

जवाबों:


191

ऐसा इसलिए है क्योंकि keysरिटर्न LazyMapCollection<[Key : Value], Key>, जिसे एक के साथ सब्सक्राइब नहीं किया जा सकता है Int। इसे संभालने का एक तरीका यह है कि डिक्शनरी startIndexद्वारा डिक्शनरी को आगे बढ़ाया जाए जिसे आप उदाहरण के लिए सब्स्क्राइब करना चाहते थे:

let intIndex = 1 // where intIndex < myDictionary.count
let index = myDictionary.index(myDictionary.startIndex, offsetBy: intIndex)
myDictionary.keys[index]

एक अन्य संभावित समाधान keysइनपुट के साथ एक सरणी को इनिशियलाइज़ करना होगा , फिर आप परिणाम पर पूर्णांक सदस्यता का उपयोग कर सकते हैं:

let firstKey = Array(myDictionary.keys)[0] // or .first

याद रखें, शब्दकोश स्वाभाविक रूप से अनियंत्रित हैं, इसलिए किसी दिए गए इंडेक्स की कुंजी की अपेक्षा हमेशा न के बराबर करें।


3
संभवत: तेजी से होगा Array(myDict)[0].0क्योंकि यह कुंजी सरणी को कॉपी नहीं करेगा, और शब्दकोश की आंतरिक संरचनाओं को कॉपी नहीं करना चाहिए, हालांकि यह हो सकता है।
डेविड बेरी

5
ध्यान रखें कि इस बात के बारे में कोई वादा नहीं है कि यह किस कुंजी पर वापस आएगा, लेकिन "दृश्य" प्रकार के बारे में अच्छा नोट जो वापस आ गया है। मेरा उत्तर हटा दिया गया क्योंकि यह वास्तव में प्रश्न पर लागू नहीं हुआ था।
रॉब नेपियर

9
यह स्पष्ट करने के लिए कि रोब क्या कह रहा है, जबकि ऐसा लग सकता है कि चाबियों को हमेशा हर बार एक ही आदेश दिया जाता है, यह मामला नहीं है और बस एक कार्यान्वयन विवरण है। यह बहुत संभव है कि आप कुंजी "फू" जोड़ सकते हैं और आंतरिक प्रतिनिधित्व पूरी तरह से शब्दकोश को फिर से व्यवस्थित करेगा। एक शब्दकोश कुंजी-मूल्य जोड़े का एक अनियंत्रित संग्रह है। इसलिए, ऊपर दिया गया जवाब खतरनाक धारणाएं बना रहा है जो सच नहीं है।
जैक लॉरेंस

8
यदि आपको किसी विशिष्ट क्रम में कुंजियों की आवश्यकता है, तो उनकी एक सरणी रखें। फिर आप उनका उपयोग कर सकते हैं myDict[keysArray[0]]
ज़ेव ईसेनबर्ग

1
काम नहीं करता है ...'NSDictionary' is not convertible to '_ArrayBuffer<T>'
क्रिस

53

स्विफ्ट 3: Array()ऐसा करने के लिए उपयोगी हो सकता है।

चाबी देना :

let index = 5 // Int Value
Array(myDict)[index].key

मूल्य प्राप्त करें:

Array(myDict)[index].value

यह मेरे लिए स्विफ्ट 3 के लिए काम करता है। समझ में नहीं आता कि क्यों बनाया गया ऐरे को फिर से व्यवस्थित किया गया है। कोई विचार?
स्लेर्टी बार्टफास्ट

धन्यवाद इससे मुझे मदद मिली
ANE

1
@josef इसके बारे में क्या है काउंटर सहज? शब्दकोश कुंजी, मूल्य जोड़े हैं, इसलिए सूचकांक का विचार ठीक नहीं है। एरे को इंडेक्स द्वारा एक्सेस किया जाता है, इसलिए यह एक शब्दकोश को एक सरणी में बदल देता है, और फिर इसे इंडेक्स द्वारा एरे को एक्सेस करता है। एक शब्दकोश ["a": 1, "b": 2], जैसे शब्दकोशों की एक सरणी में बदल दिया जा सकता है [[key: "a", value: 1], [key: "b", value: 2]], यह तब सूचकांक द्वारा पहुँचा जा सकता है।
पीटर आर

29

सूचकांक द्वारा शब्दकोश में कुंजियों और मूल्यों तक पहुंचने के लिए एक छोटा विस्तार दिया गया है:

extension Dictionary {
    subscript(i: Int) -> (key: Key, value: Value) {
        return self[index(startIndex, offsetBy: i)]
    }
}

3
'एडवांस' एपीआई को स्विफ्ट 2.0 के उपयोग में हटा दिया गया है - स्वयं [self.startIndex.advancedBy (i)] -
रोमेन

2
@TomSawyer शब्दकोशों का आदेश नहीं दिया गया है।
जोस रामिरेज़

12

आप एक शब्दकोष पर पुनरावृत्ति कर सकते हैं और एक इंडेक्स फॉर-इन और एन्युमरेट के साथ ले सकते हैं (जैसे अन्य लोगों ने कहा है, इसकी कोई गारंटी नहीं है कि यह नीचे की तरह आदेश दिया जाएगा)

let dict = ["c": 123, "d": 045, "a": 456]

for (index, entry) in enumerate(dict) {
    println(index)   // 0       1        2
    println(entry)   // (d, 45) (c, 123) (a, 456)
}

अगर आप पहले छांटना चाहते हैं ..

var sortedKeysArray = sorted(dict) { $0.0 < $1.0 }
println(sortedKeysArray)   // [(a, 456), (c, 123), (d, 45)]

var sortedValuesArray = sorted(dict) { $0.1 < $1.1 }
println(sortedValuesArray) // [(d, 45), (c, 123), (a, 456)]

फिर पुनरावृति।

for (index, entry) in enumerate(sortedKeysArray) {
    println(index)    // 0   1   2
    println(entry.0)  // a   c   d
    println(entry.1)  // 456 123 45
}

यदि आप एक आदेशित शब्दकोश बनाना चाहते हैं, तो आपको जेनरिक में देखना चाहिए।


1
क्या होगा यदि मैं 456 के बराबर सूचकांक के लिए खोज करना चाहता था?
फेमी टेक

2
@ मोम, यह पुरानी स्विफ्ट वाक्य रचना है। अब आप उपयोग कर सकते हैं: dict.enumerated().forEach { (index, element) in ... }
मैथ्यू कोरपोराल

8

से https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/CollectionTypes.html :

यदि आपको किसी API के साथ किसी शब्दकोश की कुंजियों या मानों का उपयोग करने की आवश्यकता है, जो एक ऐरे उदाहरण लेता है, तो कुंजियों या मानों के साथ एक नई सरणी शुरू करें:

let airportCodes = [String](airports.keys) // airportCodes is ["TYO", "LHR"]   
let airportNames = [String](airports.values) // airportNames is ["Tokyo", "London Heathrow"]

5

स्विफ्ट 3. पहले तत्व के लिए उदाहरण

let wordByLanguage = ["English": 5, "Spanish": 4, "Polish": 3, "Arabic": 2]

if let firstLang = wordByLanguage.first?.key {
    print(firstLang)  // English
}

3
क्या होगा यदि मैं सूचकांक प्राप्त करना चाहता हूं जहां कुंजी पोलिश है?
फेमी टेक

5

में स्विफ्ट 3 दिए गए इंडेक्स पर कुंजी-मान पेयर (टपल) प्राप्त करने के लिए इस कोड का उपयोग करने का प्रयास करें:

extension Dictionary {
    subscript(i:Int) -> (key:Key,value:Value) {
        get {
            return self[index(startIndex, offsetBy: i)];
        }
    }
}

3

यहां एक उदाहरण है, स्विफ्ट 1.2 का उपयोग करना

var person = ["name":"Sean", "gender":"male"]
person.keys.array[1] // "gender", get a dictionary key at specific index 
person.values.array[1] // "male", get a dictionary value at specific index

3

स्विफ्ट 4


थोड़ा ऑफ-टॉपिक: लेकिन यहाँ है अगर आपके पास डिरेस का ऐरे है यानी: [[स्ट्रिंग: स्ट्रिंग]]

var array_has_dictionary = [ // Start of array

   // Dictionary 1

   [ 
     "name" : "xxxx",
     "age" : "xxxx",
     "last_name":"xxx"
   ],

   // Dictionary 2

   [ 
     "name" : "yyy",
     "age" : "yyy",
     "last_name":"yyy"
   ],

 ] // end of array


cell.textLabel?.text =  Array(array_has_dictionary[1])[1].key
// Output: age -> yyy

1
मैं आपके उदाहरण में उस आइटम का सूचकांक कैसे प्राप्त कर सकता हूं जिसकी उम्र = xxxx है?
फेमिक टेक

1
arrayIndex = 0, ageDictIndex = 1, Array (array_has_dEDIA [arrayndndex] .keys) [ageDictIndex] = xxxx
Kristian

@FamicTech, क्रिस आपके प्रश्न का उत्तर
सुहैब

0

मैं जावा में एक LinkedHashMap की तरह कुछ के लिए देख रहा था। अगर मैं गलत नहीं हूं तो न तो स्विफ्ट और न ही ऑब्जेक्टिव-सी एक है।

मेरा प्रारंभिक विचार मेरे शब्दकोश को एक ऐरे में लपेटना था। [[String: UIImage]]लेकिन तब मुझे एहसास हुआ कि शब्दकोश से चाबी Array(dict)[index].keyहथियाना निराला था इसलिए मैं टुपल्स के साथ चला गया। अब मेरी सरणी दिखती है [(String, UIImage)]इसलिए मैं इसे पुनः प्राप्त कर सकता हूं tuple.0। कोई और इसे एक ऐरे में परिवर्तित कर रहा है। बस मेरे 2 सेंट।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.