Ответ 1
Swift 3 и Swift 4
componentArray = Array(dict.keys) // for Dictionary
componentArray = dict.allKeys // for NSDictionary
Попытка заполнить массив строками из ключей словаря в swift.
var componentArray: [String]
let dict = NSDictionary(contentsOfFile: NSBundle.mainBundle().pathForResource("Components", ofType: "plist")!)
componentArray = dict.allKeys
Это возвращает ошибку: "AnyObject", не идентичная строке
Также попробовал
componentArray = dict.allKeys as String
но get: 'String' не конвертируется в [String]
Swift 3 и Swift 4
componentArray = Array(dict.keys) // for Dictionary
componentArray = dict.allKeys // for NSDictionary
С Swift 3, Dictionary
имеет свойство keys
. keys
имеет следующее объявление:
var keys: LazyMapCollection<Dictionary<Key, Value>, Key> { get }
Коллекция, содержащая только ключи словаря.
Обратите внимание, что LazyMapCollection
, который можно легко сопоставить с Array
с Array
init(_:)
initializer.
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]
В более общем виде следующий код на игровой площадке показывает, как получить массив строк ([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]
Следующий код игровой площадки показывает, как получить массив строк ([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
componentArray = [String] (dict.keys)
dict.allKeys
не является строкой. Это [String]
, как указано в сообщении об ошибке (предполагая, конечно, что все клавиши - это все, что вы утверждаете, когда вы это говорите).
Итак, начинайте, набрав componentArray
как [AnyObject]
, потому что это то, как он вводится в API Cocoa, или, если вы отбрасываете dict.allKeys
, отбрасываете его на [String]
, потому что это как вы набрали componentArray
.
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
}
}
NSDictionary - это класс (передача по ссылке) Словарь - это структура (передача по значению)
====== Массив из NSDictionary ======
NSDictionary имеет allKeys, а allValues получают свойства с типом [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)
====== Array From Dictionary ======
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)
dict.keys.sorted()
это дает [String] https://developer.apple.com/documentation/swift/array/2945003-sorted
Этот ответ будет для быстрого словаря со строковыми ключами. Как этот ниже.
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()
Из официальной документации 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"]"
// 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 }
}
}