2016-07-31 10 views
7

मेरे पास [String:String] शब्दकोश है। मैं स्ट्रिंग "एस" युक्त किसी भी कुंजी से जुड़े मान प्राप्त करना चाहता हूं। आदेश कोई फर्क नहीं पड़ता।स्विफ्ट शब्दकोश में स्ट्रिंग युक्त एक कुंजी खोजें

यह मृत आसान है: बस सभी चाबियाँ प्राप्त करें, फिर से शुरू करें, पहले स्थिति को मेल करें।

हालांकि, मैं इसे एक तेज़-जैसे सुरुचिपूर्ण दृष्टिकोण का उपयोग करना चाहता हूं। कुछ filter या map फ़ंक्शंस का उपयोग कर कुछ। और वह मैं कहाँ खो जाना है ...

उत्तर

9

जब से तुम केवल में रुचि रखते हैं किसी भी मिलान मूल्य, आप उपयोग कर सकते हैं पहले मिलान शब्दकोश प्रविष्टि को खोजने के लिए indexOf() विधि। यह काम करता है क्योंकि एक शब्दकोश कुंजी/मूल्य जोड़े का संग्रह है।

स्विफ्ट 2:

let dict = ["foo": "bar", "PQRS": "baz"] 
let searchTerm = "S" 

if let index = dict.indexOf({ (key, _) in key.containsString(searchTerm) }) { 
    let value = dict[index].1 
    print(value) 
} else { 
    print("no match") 
} 

जैसे ही मिलान कुंजी पाया जाता है, विधेय रिटर्न true और गणन बंद हो जाता है। index एक "शब्दकोश सूचकांक" है जो को सीधे शब्दकोश प्रविष्टि प्राप्त करने के लिए उपयोग किया जा सकता है।

if let entry = dict.first(where: { (key, _) in key.contains(searchTerm) }) { 
    print(entry.value) 
} else { 
    print("no match") 
} 
:

एक केस-संवेदी कुंजी खोज के लिए, में स्विफ्ट 3 आप first(where:) उपयोग कर सकते हैं पहले मिलान तत्व को खोजने के लिए, यह एक शब्दकोश देखने की बचत होती है द्वारा

{ 
    (key, _) in key.rangeOfString(searchTerm, options: .CaseInsensitiveSearch) != nil 
} 

विधेय की जगह

केस-असंवेदनशील कुंजी खोज के लिए,

द्वारा अनुमान को प्रतिस्थापित करें
+0

अगर मुझे केस असंवेदनशीलता की आवश्यकता नहीं है क्योंकि मुझे पता है कि तार सभी कैप्स हैं, तो क्या मैं key.range() की बजाय key.contains() का उपयोग कर सकता हूं या key.range() तेज है? – Adeline

+0

@ एडलाइन: मुझे नहीं लगता कि इससे कोई फर्क पड़ता है, लेकिन 'key.contains()' सरल है, इसलिए मैं इसका उपयोग करूंगा। –

+0

सभी तीन उत्तरों मान्य हैं, लेकिन उनका सबसे तेज़ है। – Adeline

4

आप filter, contains और first उपयोग कर सकते हैं "एस" लगता है:

स्विफ्ट 2

if let key = yourDictionary.keys.filter({ $0.lowercaseString.characters.contains("s") }).first, let result = yourDictionary[key] { 
    print(result) 
} 

स्विफ्ट 3

if let key = yourDictionary.keys.filter({ $0.lowercased().contains("s") }).first, let result = yourDictionary[key] { 
    print(result) 
} 

एक टिप्पणी में, @Hamish ऑफ़र स्विफ्ट 3 के लिए इस उत्कृष्ट विकल्प: के बजाय

filter({ ... }).first 

आप उपयोग कर सकते

first(where: { ... }) 

उदाहरण:

if let key = yourDictionary.keys.first(where: { $0.lowercased().contains("s") }), let result = yourDictionary[key] { 
    print(result) 
} 
+1

ध्यान दें कि स्विफ्ट 3 में, आप ऐसा करने के लिए ['पहले (कहां:)'] (http://swiftdoc.org/v3.0/protocol/Sequence/#func-first_) का भी उपयोग कर सकते हैं। – Hamish

+0

@ हैमिश यह एक उत्कृष्ट विचार है, धन्यवाद। क्या आप इसे किसी उत्तर में उपयोग करने जा रहे हैं, या क्या मैं इसे अपने (इसे पाठ्यक्रम के साथ) जोड़ता हूं? – Moritz

+0

@EricD मुझे कोई फर्क नहीं पड़ता :) मुझे पता है कि मार्टिन ने इसे अपने उत्तर में भी इस्तेमाल किया है (डरावना समय वहाँ!), इसलिए मुझे वास्तव में इसके लिए कोई अलग जवाब देने में कोई बिंदु नहीं दिख रहा है। – Hamish

4

आप flatMap और containsString साथ यह कर सकते हैं:

स्विफ्ट 2.x:

let dict = ["one": "1", "two": "2", "three": "3", "four": "4", "five": "5", "six": "6"] 

let results = dict.flatMap { (key, value) in key.lowercaseString.containsString("o") ? value : nil } 

print(results) 

आउटपुट:

["4", "1", "2"] 
print(results.first ?? "Not found") 
4 

या यदि आप गुप्त एक लाइनर्स प्यार:

let first = dict.flatMap { $0.lowercaseString.containsString("o") ? $1 : nil }.first ?? "Not found" 

स्विफ्ट 3 के लिए:

let dict = ["one": "1", "two": "2", "three": "3", "four": "4", "five": "5", "six": "6"] 

let results = dict.flatMap { (key, value) in key.lowercased().contains("o") ? value : nil } 

print(results) 
print(results.first ?? "Not Found") 

या यदि आप गुप्त एक लाइनर्स प्यार:

let first = dict.flatMap { $0.lowercased().contains("o") ? $1 : nil }.first ?? "Not Found" 
संबंधित मुद्दे