前言
持续学习
偷师于大佬
把Model数组转字典。
struct Data {
var name: String
}
// mock 数据
var dataList = Array(0..<10).map { Data.init(name: "data \($0)") }
将Array以它的`name`为`key`,它本身作为`value`,放到一个数组里。
常规做法1:
var dataMap = Dictionary<String, Data>()
for i in 0..<dataList.count {
dataMap[dataList[i].name] = dataList[i]
}
常规做法2:
var dataMap = Dictionary<String, Data>()
for data in dataList {
dataMap[data.name] = data
}
一句话代码:
var dataMap = Dictionary.init(dataList.map { ($0.name, $0) }) { $1 }
解析:
let dataPairList = dataList.map { ($0.name, $0) }
dataMap = Dictionary.init(dataPairList, uniquingKeysWith: { (old, new) in
new
})
- 第一行里,把 key 和 value 拆成了键值对(元组),结果就是下面构造方法的第一个参数。
- 第二行里,构造方法的第二个参数是一个闭包,用来决定当键重复时,用哪个当值。在例子里直接使用新的 model 覆盖旧的。然后直接构造字典。
Dictionary 的这个构造方法的签名是:
/// Creates a new dictionary from the key-value pairs in the given sequence,
/// using a combining closure to determine the value for any duplicate keys.
///
/// You use this initializer to create a dictionary when you have a sequence
/// of key-value tuples that might have duplicate keys. As the dictionary is
/// built, the initializer calls the `combine` closure with the current and
/// new values for any duplicate keys. Pass a closure as `combine` that
/// returns the value to use in the resulting dictionary: The closure can
/// choose between the two values, combine them to produce a new value, or
/// even throw an error.
///
/// The following example shows how to choose the first and last values for
/// any duplicate keys:
///
/// let pairsWithDuplicateKeys = [("a", 1), ("b", 2), ("a", 3), ("b", 4)]
///
/// let firstValues = Dictionary(pairsWithDuplicateKeys,
/// uniquingKeysWith: { (first, _) in first })
/// // ["b": 2, "a": 1]
///
/// let lastValues = Dictionary(pairsWithDuplicateKeys,
/// uniquingKeysWith: { (_, last) in last })
/// // ["b": 4, "a": 3]
///
/// - Parameters:
/// - keysAndValues: A sequence of key-value pairs to use for the new
/// dictionary.
/// - combine: A closure that is called with the values for any duplicate
/// keys that are encountered. The closure returns the desired value for
/// the final dictionary.
@inlinable public init<S>(_ keysAndValues: S, uniquingKeysWith combine: (Value, Value) throws -> Value) rethrows where S : Sequence, S.Element == (Key, Value)
这个方法由 Swift 4 引入。
自己动手,丰衣足食
看完大佬的代码,还是有点不解,自己再写一遍,加深记忆
解析代码等价于
let dataPairList = dataList.map { ($0.name, $0) }
// 等价于
let dataPairList = dataList.map { data -> (String, Data) in
// $0:第一个参数,这里是map中的变量
let tuple = (data.name, data)
return tuple
}
// 同理,mock数据
var dataList = Array(0..<10).map { Data.init(name: "data \($0)") }
var dataList = Array(0..<10).map { index in
Data.init(name: "data \(index)")
}