mat*_*att 9 arrays tuples swift
我有一组键值对:
let arr = [(key:"hey", value:["ho"]), (key:"ha", value:["tee", "hee"])]
Run Code Online (Sandbox Code Playgroud)
我将它分成两个数组,如下所示:
let (keys, values) = (arr.map{$0.key}, arr.map{$0.value})
Run Code Online (Sandbox Code Playgroud)
实际上,这是相反的zip- 我正在将一组元组转换为两个数组.
但我不喜欢我map两次调用的事实,因为这意味着我将循环遍历数组两次.然而,我也不想事先将两个目标数组声明为空数组并在追加时循环一次,例如使用forEach.是否有一些很棒的Swifty成语可以将我的元组数组解压缩成两个数组?
Rob*_*Rob 10
在Swift 4中,您可以使用reduce(into:):
let (keys, values) = arr.reduce(into: ([String](), [[String]]())) {
$0.0.append($1.key)
$0.1.append($1.value)
}
Run Code Online (Sandbox Code Playgroud)
你说:
然而,我也不想事先将两个目标数组声明为空数组并在追加时循环一次,例如使用
forEach.
就个人而言,这正是我要做的.我只想编写一个执行此操作的函数(这样您就不会使用该模式填充代码).但我认为以下内容比reduce模式更清晰直观,但不会遭受双重map方法的低效率.
/// Unzip an `Array` of key/value tuples.
///
/// - Parameter array: `Array` of key/value tuples.
/// - Returns: A tuple with two arrays, an `Array` of keys and an `Array` of values.
func unzip<K, V>(_ array: [(key: K, value: V)]) -> ([K], [V]) {
var keys = [K]()
var values = [V]()
keys.reserveCapacity(array.count)
values.reserveCapacity(array.count)
array.forEach { key, value in
keys.append(key)
values.append(value)
}
return (keys, values)
}
Run Code Online (Sandbox Code Playgroud)
或者,如果你觉得有必要成功extension,你也可以这样做:
extension Array {
/// Unzip an `Array` of key/value tuples.
///
/// - Returns: A tuple with two arrays, an `Array` of keys and an `Array` of values.
func unzip<K, V>() -> ([K], [V]) where Element == (key: K, value: V) {
var keys = [K]()
var values = [V]()
keys.reserveCapacity(count)
values.reserveCapacity(count)
forEach { key, value in
keys.append(key)
values.append(value)
}
return (keys, values)
}
}
Run Code Online (Sandbox Code Playgroud)
无论你想要实现这个,但是当你在一个函数中使用它时,你可以支持清晰度和意图.
reduce(into:)很棒,但不要忘记reserveCapacity防止重新分配开销:
extension Array {
func unzip<T1, T2>() -> ([T1], [T2]) where Element == (T1, T2) {
var result = ([T1](), [T2]())
result.0.reserveCapacity(self.count)
result.1.reserveCapacity(self.count)
return reduce(into: result) { acc, pair in
acc.0.append(pair.0)
acc.1.append(pair.1)
}
}
}
Run Code Online (Sandbox Code Playgroud)
我会应用KISS原则:
extension Array {
func unzip<T1, T2>() -> ([T1], [T2]) where Element == (T1, T2) {
var result = ([T1](), [T2]())
result.0.reserveCapacity(self.count)
result.1.reserveCapacity(self.count)
for (a, b) in self {
result.0.append(a)
result.1.append(b)
}
return result
}
}
let arr = [
(key: "hey", value: ["ho"]),
(key: "ha", value: ["tee", "hee"])
]
let unzipped = (arr as [(String, [String])]).unzip()
print(unzipped)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1101 次 |
| 最近记录: |