【问题标题】:Array from dictionary keys in swiftswift中字典键的数组
【发布时间】:2014-12-10 17:44:42
【问题描述】:

尝试用 swift 中字典中键的字符串填充数组。

var componentArray: [String]

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

这会返回一个错误:“AnyObject”与字符串不同

也试过了

componentArray = dict.allKeys as String 

但得到:'String' 不能转换为 [String]

【问题讨论】:

    标签: ios arrays xcode dictionary swift


    【解决方案1】:

    斯威夫特 3 和斯威夫特 4

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

    【讨论】:

    • 有趣的是,在一个 for 循环中 - for name in dict.allKeys - 'name' 变成了一个字符串,可以打印和处理。
    • dict 没有键方法。它是 NSDictionary 的一个实例,而不是 Dictionary。
    • dict.map { $0.key }
    • 请注意,此方法不会保留键的顺序
    【解决方案2】:

    在 Swift 3 中,Dictionary 有一个 keys 属性。 keys 有以下声明:

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

    仅包含字典键的集合。

    请注意,LazyMapCollection 可以通过 Arrayinit(_:) 初始化程序轻松映射到 Array


    NSDictionary[String]

    以下 iOS AppDelegate class sn-p 展示了如何使用 keys 属性从 NSDictionary 获取字符串数组 ([String]):

    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: Int]) 的字典中的 keys 属性获取字符串数组 ([String]):

    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 代码显示了如何使用 keys 属性从具有整数键和字符串值 ([Int: String]) 的字典中获取字符串数组 ([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&lt;String, String&gt;.Keys - 你知道我们什么时候想要使用这种类型以及如何使用吗?
    【解决方案3】:

    Swift 中字典键的数组

    componentArray = [String] (dict.keys)
    

    【讨论】:

    • 我不知道,为什么人们不喜欢简写语法,而它更容易理解。
    • 我无法告诉你你为我解决了多少麻烦。谢谢!!!
    【解决方案4】:

    dict.allKeys 不是字符串。它是一个[String],正如错误消息告诉您的那样(当然,假设键 都是字符串;这正是您所说的断言)。

    所以,要么首先将componentArray 输入为[AnyObject],因为这就是它在 Cocoa API 中的输入方式,否则,如果您将dict.allKeys 转换为[String],因为这就是你输入了componentArray

    【讨论】:

    • 这似乎不再正确。在 Swift 4.2 中,dict.keys(替换 .allKeys)不是 [String],它是 [Dictionary.Keys] 并且必须在分配给 [String] 类型的变量之前强制转换 @santo 似乎有如何做到这一点的最简单的工作示例。
    【解决方案5】:

    你可以像这样使用dictionary.map:

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

    解释: Map 遍历 myDictionary 并接受每个键值对作为 $0。从这里您可以获得 $0.key 或 $0.value。在尾随闭包 {} 内,您可以转换每个元素并返回该元素。既然你想要 $0 并且你想要它作为一个字符串,那么你可以使用 String($0.key) 进行转换。您将转换后的元素收集到一个字符串数组中。

    【讨论】:

      【解决方案6】:
      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
          }
      }
      

      【讨论】:

        【解决方案7】:

        【讨论】:

          【解决方案8】:

          NSDictionary类(通过引用传递) 字典结构(传值 ====== 来自 NSDictionary 的数组 ======

          NSDictionary 具有 allKeysallValues 获取属性 输入 [任何].

            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)
          

          ====== 字典中的数组 ======

          Dictionary 的 keysvalues 属性的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)
          

          【讨论】:

            【解决方案9】:

            来自官方Array Apple documentation

            init(_:) - 创建一个包含序列元素的数组。

            声明

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

            参数

            s - 要转换为数组的元素序列。

            讨论

            您可以使用此初始化程序从符合序列协议的任何其他类型创建数组...您还可以使用此初始化程序将复杂的序列或集合类型转换回数组。 例如,字典的 keys 属性不是具有自己存储的数组,它是一个集合,仅在访问字典时才从字典中映射其元素,从而节省分配数组所需的时间和空间。但是,如果您需要将这些键传递给采用数组的方法,请使用此初始化程序将该列表从其 LazyMapCollection&lt;Dictionary&lt;String, Int&gt;, Int&gt; 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"]"
            

            【讨论】:

              【解决方案10】:

              斯威夫特 5

              var dict = ["key1":"Value1", "key2":"Value2"]
              
              let k = dict.keys
              
              var a: [String]()
              a.append(contentsOf: k)
              

              这对我有用。

              【讨论】:

                【解决方案11】:

                这个答案将适用于带有字符串键的快速字典。 喜欢下面这张

                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()
                

                【讨论】:

                  【解决方案12】:
                  // 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 }
                      }
                  }
                  

                  【讨论】:

                  • 你好!虽然此代码 sn-p 可能是解决方案,但including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-05-10
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-08-23
                  • 1970-01-01
                  • 2017-03-27
                  • 1970-01-01
                  相关资源
                  最近更新 更多