快速从字典键数组


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]

Answers:



55

使用Swift 3,Dictionary具有一个keys属性。keys具有以下声明:

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

仅包含字典键的集合。

请注意,LazyMapCollection可以轻松将其映射到Array带有Arrayinit(_:)初始化程序。


NSDictionary[String]

以下iOS AppDelegate类代码段显示了如何[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-当我们想要使用该类型时,您有什么见识?如何使用?
bshirley19年

46

Swift中字典键的数组

componentArray = [String] (dict.keys)

我不知道,为什么人们不喜欢速记语法,却更容易理解。
娜塔莎

9

dict.allKeys不是字符串。这是一个[String],正是因为错误消息告诉你(假设,当然,这两把钥匙所有字符串,这是当你说你是断言到底是什么)。

因此,要么从键入componentArrayas 开始[AnyObject],因为这是在Cocoa 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

NSDictionaryClass(通过引用传递) DictionaryStructure(通过值传递) ======来自NSDictionary的数组======NSDictionary是类类型 字典是关键和价值的结构

NSDictionary具有allKeysallValues获得类型为[Any]的属性。NSDictionary具有allkey和allvalue的[Any]属性

  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参考,用于Dictionary的 属性。 在此处输入图片说明

在此处输入图片说明

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-要变成数组的元素序列。

讨论区

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

说明:Map遍历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
嘿!尽管此代码段可能是解决方案,但提供说明确实有助于提高您的帖子质量。请记住,您将来会为读者回答这个问题,而这些人可能不知道您提出代码建议的原因。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.