อาร์เรย์จากปุ่มพจนานุกรมอย่างรวดเร็ว


256

พยายามเติมอาเรย์ด้วยสตริงจากกุญแจในพจนานุกรมอย่างรวดเร็ว

var componentArray: [String]

let dict = NSDictionary(contentsOfFile: NSBundle.mainBundle().pathForResource("Components", ofType: "plist")!)
componentArray = dict.allKeys

ส่งกลับข้อผิดพลาดของ: 'AnyObject' ไม่เหมือนกับสตริง

ยังพยายาม

componentArray = dict.allKeys as String 

แต่รับ: 'String' ไม่สามารถแปลงเป็น [String]

คำตอบ:


534

Swift 3 & Swift 4

componentArray = Array(dict.keys) // for Dictionary

componentArray = dict.allKeys // for NSDictionary

น่าสนใจใน for for loop - สำหรับชื่อใน dict.allKeys - 'name' กลายเป็นสตริงและสามารถพิมพ์และประมวลผลได้
green_knight

dict ไม่มีเมธอด keys มันเป็นตัวอย่างของ NSDictionary ไม่ใช่พจนานุกรม
Womble

2
dict.map {$ 0.key}
Nilanshu Jaiswal

55

ด้วย Swift 3 Dictionaryมีkeysคุณสมบัติ keysมีการประกาศดังต่อไปนี้:

var keys: LazyMapCollection<Dictionary<Key, Value>, Key> { get }

ชุดรวมที่มีเพียงปุ่มของพจนานุกรม

โปรดทราบว่าLazyMapCollectionสามารถแมปArrayกับตัวเริ่มต้นArrayของด้วยได้อย่างง่ายดายinit(_:)


ตั้งแต่NSDictionaryถึง[String]

AppDelegateตัวอย่างคลาสiOS ต่อไปนี้แสดงวิธีรับอาร์เรย์ของสตริง ( [String]) โดยใช้keysคุณสมบัติจากNSDictionary:

ป้อนคำอธิบายรูปภาพที่นี่

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let string = Bundle.main.path(forResource: "Components", ofType: "plist")!
    if let dict = NSDictionary(contentsOfFile: string) as? [String : Int] {
        let lazyMapCollection = dict.keys
        
        let componentArray = Array(lazyMapCollection)
        print(componentArray)
        // prints: ["Car", "Boat"]
    }
    
    return true
}

ตั้งแต่[String: Int]ถึง[String]

โดยทั่วไปแล้วโค้ด Playground ต่อไปนี้จะแสดงวิธีรับอาเรย์ของสตริง ( [String]) โดยใช้keysคุณสมบัติจากพจนานุกรมที่มีคีย์สตริงและค่าจำนวนเต็ม ( [String: Int]):

let dictionary = ["Gabrielle": 49, "Bree": 32, "Susan": 12, "Lynette": 7]
let lazyMapCollection = dictionary.keys

let stringArray = Array(lazyMapCollection)
print(stringArray)
// prints: ["Bree", "Susan", "Lynette", "Gabrielle"]

ตั้งแต่[Int: String]ถึง[String]

รหัส Playground ต่อไปนี้แสดงวิธีรับอาร์เรย์ของสตริง ( [String]) โดยใช้keysคุณสมบัติจากพจนานุกรมที่มีคีย์จำนวนเต็มและค่าสตริง ( [Int: String]):

let dictionary = [49: "Gabrielle", 32: "Bree", 12: "Susan", 7: "Lynette"]
let lazyMapCollection = dictionary.keys
    
let stringArray = Array(lazyMapCollection.map { String($0) })
// let stringArray = Array(lazyMapCollection).map { String($0) } // also works
print(stringArray)
// prints: ["32", "12", "7", "49"]

ขอบคุณสำหรับรายละเอียด ใน Swift 4.x ประเภทคือDictionary<String, String>.Keys- คุณมีข้อมูลเชิงลึกใด ๆ เมื่อเราต้องการใช้ประเภทนั้นและอย่างไร
bshirley

46

อาร์เรย์จากปุ่มพจนานุกรมใน Swift

componentArray = [String] (dict.keys)

ฉันไม่รู้ทำไมคนไม่ชอบใช้ชวเลขไวยากรณ์ในขณะที่มันชัดเจนกว่าที่จะเข้าใจ
นาตาชา

9

dict.allKeysไม่ใช่สตริง มันเป็น[String]เหมือนที่เกิดข้อผิดพลาดจะบอกคุณ (สมมติว่าแน่นอนว่ากุญแจอยู่สตริงทั้งหมดนี่คือสิ่งที่คุณยืนยันเมื่อคุณพูดอย่างนั้น)

ดังนั้นไม่ว่าจะเริ่มต้นด้วยการพิมพ์componentArrayเป็น[AnyObject]เพราะนั่นคือวิธีการที่จะพิมพ์ลงในโกโก้ API หรืออื่น ๆ ถ้าคุณโยนdict.allKeysทิ้งมันไปเพราะนั่นคือวิธีการที่คุณได้พิมพ์[String]componentArray


1
ดูเหมือนว่าจะไม่เป็นความจริงอีกต่อไป ใน Swift 4.2 dict.keys (ซึ่งแทนที่. allKeys) ไม่ใช่ [String] มันคือ [Dictionary <String, Any> .Keys] และต้องทำการส่งก่อนกำหนดประเภทตัวแปร [String] @santo ดูเหมือนว่าจะมี ตัวอย่างการทำงานที่ง่ายที่สุดของวิธีการทำเช่นนั้น
timeSmith

5
extension Array {
    public func toDictionary<Key: Hashable>(with selectKey: (Element) -> Key) -> [Key:Element] {
        var dict = [Key:Element]()
        for element in self {
            dict[selectKey(element)] = element
        }
        return dict
    }
}

3

NSDictionaryคือคลาส (ผ่านการอ้างอิง) พจนานุกรมคือโครงสร้าง (ผ่านตามค่า ) ====== อาร์เรย์จาก NSDictionary ======NSDictionary เป็นประเภทชั้น พจนานุกรมคือโครงสร้างของคีย์และค่า

NSDictionary มีAllKeysและallValuesได้รับคุณสมบัติที่มีประเภท[ใด]NSDictionary ได้รับคุณสมบัติใด ๆ สำหรับปุ่มและค่าทั้งหมด

  let objesctNSDictionary = 
    NSDictionary.init(dictionary: ["BR": "Brazil", "GH": "Ghana", "JP": "Japan"])
            let objectArrayOfAllKeys:Array = objesctNSDictionary.allKeys
            let objectArrayOfAllValues:Array = objesctNSDictionary.allValues
            print(objectArrayOfAllKeys)
            print(objectArrayOfAllValues)

====== อาร์เรย์จากพจนานุกรม ======

การอ้างอิง Apple สำหรับคุณสมบัติ คีย์และค่าของพจนานุกรม ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

let objectDictionary:Dictionary = 
            ["BR": "Brazil", "GH": "Ghana", "JP": "Japan"]
    let objectArrayOfAllKeys:Array = Array(objectDictionary.keys)          
    let objectArrayOfAllValues:Array = Array(objectDictionary.values)
    print(objectArrayOfAllKeys)
    print(objectArrayOfAllValues)


3

จากเอกสารของ Array Appleอย่างเป็นทางการ :

init(_:) - สร้างอาร์เรย์ที่มีองค์ประกอบของลำดับ

การประกาศ

Array.init<S>(_ s: S) where Element == S.Element, S : Sequence

พารามิเตอร์

s - ลำดับขององค์ประกอบที่จะเปลี่ยนเป็นอาร์เรย์

อภิปรายผล

คุณสามารถใช้ initializer นี้เพื่อสร้างอาร์เรย์จากชนิดอื่นที่สอดคล้องกับโพรโทคอล Sequence ... คุณยังสามารถใช้ initializer นี้เพื่อแปลงลำดับที่ซับซ้อนหรือประเภทคอลเลกชันกลับไปเป็นอาร์เรย์ ตัวอย่างเช่นคุณสมบัติคีย์ของพจนานุกรมไม่ได้เป็นอาร์เรย์ที่มีที่เก็บข้อมูลของตัวเองมันเป็นคอลเลกชันที่จับคู่องค์ประกอบของมันจากพจนานุกรมเมื่อเข้าถึงเท่านั้นประหยัดเวลาและพื้นที่ที่จำเป็นในการจัดสรรอาร์เรย์ หากคุณต้องการส่งคีย์เหล่านั้นไปยังเมธอดที่รับอาเรย์ให้ใช้ initializer นี้เพื่อแปลงรายการนั้นจากประเภทของLazyMapCollection<Dictionary<String, Int>, Int> to a simple [String]มัน

func cacheImagesWithNames(names: [String]) {
    // custom image loading and caching
 }

let namedHues: [String: Int] = ["Vermillion": 18, "Magenta": 302,
        "Gold": 50, "Cerise": 320]
let colorNames = Array(namedHues.keys)
cacheImagesWithNames(colorNames)

print(colorNames)
// Prints "["Gold", "Cerise", "Magenta", "Vermillion"]"

1

คำตอบนี้จะใช้สำหรับพจนานุกรมที่รวดเร็วด้วยคีย์สตริง เช่นหนึ่งด้านล่างนี้

let dict: [String: Int] = ["hey": 1, "yo": 2, "sup": 3, "hello": 4, "whassup": 5]

นี่คือส่วนขยายที่ฉันจะใช้

extension Dictionary {
  func allKeys() -> [String] {
    guard self.keys.first is String else {
      debugPrint("This function will not return other hashable types. (Only strings)")
      return []
    }
    return self.flatMap { (anEntry) -> String? in
                          guard let temp = anEntry.key as? String else { return nil }
                          return temp }
  }
}

และฉันจะได้รับกุญแจทั้งหมดในภายหลังโดยใช้สิ่งนี้

let componentsArray = dict.allKeys()


1

คุณสามารถใช้ dictionary.map ดังนี้:

let myKeys: [String] = myDictionary.map{String($0.key) }

คำอธิบาย: แผนที่ซ้ำผ่าน myDictionary และยอมรับแต่ละคู่คีย์และค่าเป็น $ 0 จากที่นี่คุณจะได้รับ $ 0.key หรือ $ 0.value ภายในส่วนท้ายของการปิดท้าย {} คุณสามารถเปลี่ยนแต่ละองค์ประกอบและส่งคืนองค์ประกอบนั้นได้ เนื่องจากคุณต้องการ $ 0 และคุณต้องการเป็นสตริงดังนั้นคุณจึงแปลงโดยใช้ String ($ 0.key) คุณรวบรวมองค์ประกอบที่แปลงเป็นอาร์เรย์ของสตริง


-2
// Old version (for history)
let keys = dictionary.keys.map { $0 }
let keys = dictionary?.keys.map { $0 } ?? [T]()

// New more explained version for our ducks
extension Dictionary {

    var allKeys: [Dictionary.Key] {
        return self.keys.map { $0 }
    }
}

2
สวัสดี! ในขณะที่ข้อมูลโค้ดนี้อาจเป็นโซลูชันรวมถึงคำอธิบายช่วยปรับปรุงคุณภาพของโพสต์ของคุณ จำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตและคนเหล่านั้นอาจไม่ทราบสาเหตุของการแนะนำรหัสของคุณ
ปีก
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.