Pet*_*r71 35 arrays dictionary filter swift
我有一个大型数组,需要通过键(查找)访问它,所以我需要创建字典.在Swift 3.0中是否有内置函数可以这样做,还是我需要自己编写?
首先,我将需要它用于具有键"String"的类,稍后我可以编写用于通用目的的模板版本(所有类型的数据和键).
Kam*_*com 68
是这样的(在Swift 4中)?
let dict = Dictionary(uniqueKeysWithValues: array.map{ ($0.key, $0) })
Run Code Online (Sandbox Code Playgroud)
ove*_*tor 41
我想你正在寻找这样的东西:
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
}
}
Run Code Online (Sandbox Code Playgroud)
你现在可以这样做:
struct Person {
var name: String
var surname: String
var identifier: String
}
let arr = [Person(name: "John", surname: "Doe", identifier: "JOD"),
Person(name: "Jane", surname: "Doe", identifier: "JAD")]
let dict = arr.toDictionary { $0.identifier }
print(dict) // Result: ["JAD": Person(name: "Jane", surname: "Doe", identifier: "JAD"), "JOD": Person(name: "John", surname: "Doe", identifier: "JOD")]
Run Code Online (Sandbox Code Playgroud)
如果您希望代码更通用,您甚至可以添加此扩展名Sequence
而不是Array
:
extension Sequence {
public func toDictionary<Key: Hashable>(with selectKey: (Iterator.Element) -> Key) -> [Key:Iterator.Element] {
var dict: [Key:Iterator.Element] = [:]
for element in self {
dict[selectKey(element)] = element
}
return dict
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这会导致序列被迭代,并且在某些情况下可能会产生副作用.
Bur*_*ala 39
在Swift 4上,您可以使用Dictionary的 grouping:by:
初始化程序实现此目的
例如:你有一个名为A的班级
class A {
var name: String
init(name: String) {
self.name = name
}
// .
// .
// .
// other declations and implementions
}
Run Code Online (Sandbox Code Playgroud)
接下来,您有一个A类型的对象数组
let a1 = A(name: "Joy")
let a2 = A(name: "Ben")
let a3 = A(name: "Boy")
let a4 = A(name: "Toy")
let a5 = A(name: "Tim")
let array = [a1, a2, a3, a4, a5]
Run Code Online (Sandbox Code Playgroud)
假设您要通过将所有名称按其第一个字母分组来创建字典.您使用Swifts Dictionary(grouping:by:)
来实现这一目标
let dictionary = Dictionary(grouping: array, by: { $0.name.first! })
// this will give you a dictionary
// ["J": [a1], "B": [a2, a3], "T": [a4, a5]]
Run Code Online (Sandbox Code Playgroud)
Luc*_*tti 11
正如其他人已经说过的那样,我们需要了解哪些是关键.
但是,我试图为我对你的问题的解释提供一个解决方案.
struct User {
let id: String
let firstName: String
let lastName: String
}
Run Code Online (Sandbox Code Playgroud)
在这里,我假设有2个用户
id
不能存在
let users: [User] = ...
let dict = users.reduce([String:User]()) { (result, user) -> [String:User] in
var result = result
result[user.id] = user
return result
}
Run Code Online (Sandbox Code Playgroud)
现在dict
是一本字典,其中key
是user id
和value
是user value
.
要通过它访问用户,id
您现在可以简单地写
let user = dict["123"]
Run Code Online (Sandbox Code Playgroud)
给定一个给定类型的阵列Element
,和封闭该确定key
的Element
,下面的通用函数将生成一个Dictionary
类型的[Key:Element]
func createIndex<Key, Element>(elms:[Element], extractKey:(Element) -> Key) -> [Key:Element] where Key : Hashable {
return elms.reduce([Key:Element]()) { (dict, elm) -> [Key:Element] in
var dict = dict
dict[extractKey(elm)] = elm
return dict
}
}
Run Code Online (Sandbox Code Playgroud)
例
let users: [User] = [
User(id: "a0", firstName: "a1", lastName: "a2"),
User(id: "b0", firstName: "b1", lastName: "b2"),
User(id: "c0", firstName: "c1", lastName: "c2")
]
let dict = createIndex(elms: users) { $0.id }
// ["b0": {id "b0", firstName "b1", lastName "b2"}, "c0": {id "c0", firstName "c1", lastName "c2"}, "a0": {id "a0", firstName "a1", lastName "a2"}]
Run Code Online (Sandbox Code Playgroud)
正如Martin R所指出的,reduce将为相关闭包的每次迭代创建一个新的字典.这可能会导致巨大的内存消耗.
这是createIndex
函数的另一个版本,其中空间要求是O(n),其中n是elms的长度.
func createIndex<Key, Element>(elms:[Element], extractKey:(Element) -> Key) -> [Key:Element] where Key : Hashable {
var dict = [Key:Element]()
for elm in elms {
dict[extractKey(elm)] = elm
}
return dict
}
Run Code Online (Sandbox Code Playgroud)
雨燕5
extension Array {
func toDictionary() -> [Int: Element] {
self.enumerated().reduce(into: [Int: Element]()) { $0[$1.offset] = $1.element }
}
}
Run Code Online (Sandbox Code Playgroud)
let pills = ["12", "34", "45", "67"]
let kk = Dictionary(uniqueKeysWithValues: pills.map{ ($0, "number") })
["12": "number", "67": "number", "34": "number", "45": "number"]
Run Code Online (Sandbox Code Playgroud)
swift5 swift4
此扩展适用于所有序列(包括数组),并允许您选择key 和 value:
extension Sequence {
public func toDictionary<K: Hashable, V>(_ selector: (Iterator.Element) throws -> (K, V)?) rethrows -> [K: V] {
var dict = [K: V]()
for element in self {
if let (key, value) = try selector(element) {
dict[key] = value
}
}
return dict
}
}
Run Code Online (Sandbox Code Playgroud)
例子:
let nameLookup = persons.toDictionary{($0.name, $0)}
Run Code Online (Sandbox Code Playgroud)
以下将数组转换为字典。
let firstArray = [2,3,4,5,5]
let dict = Dictionary(firstArray.map { ($0, 1) } , uniquingKeysWith: +)
Run Code Online (Sandbox Code Playgroud)