arrays - 与 Swift `zip` 相反——将元组拆分为两个数组

标签 arrays swift tuples

我有一个键值对数组:

let arr = [(key:"hey", value:["ho"]), (key:"ha", value:["tee", "hee"])]

我将它分成两个数组,如下所示:

let (keys, values) = (arr.map{$0.key}, arr.map{$0.value})

实际上,这与 zip 相反——我将一个元组数组变成两个数组。

但我不喜欢调用 map 两次,因为这意味着我在数组中循环两次。然而,我也不想事先将两个目标数组声明为空数组并在追加时循环一次,例如使用 forEach。是否有一些很棒的 Swifty 习惯用法可以将我的元组数组解压缩为两个数组?

最佳答案

在 Swift 4 中,你可以使用 reduce(into:):

let (keys, values) = arr.reduce(into: ([String](), [[String]]())) {
    $0.0.append($1.key)
    $0.1.append($1.value)
}

你说:

Yet neither do I want to declare the two target arrays beforehand as empty arrays and loop once while appending, e.g. with 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)
}

或者,如果您觉得有必要将其作为扩展,您也可以这样做:

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)
    }
}

随心所欲地实现它,但是当您将它放在函数中时,您可以更加清晰和明确。

关于arrays - 与 Swift `zip` 相反——将元组拆分为两个数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46043902/

相关文章:

arrays - C语言中数组变量是如何存储的? (不是内存本身,而是命名变量中的指针)

javascript - Three.JS中使用switch语句加载多个对象

ios - 用UIScrollView缩放时,无法正确滚动到下端

python - 尝试使用递归将文件路径拆分为元组

c# - 将对象列表转换为元组列表而不进行迭代

arrays - VB.NET数组参数机制,byval和byref

javascript - chop 对象数组中的文本?

swift - 水平 UITableView - Swift

swift - 工作表 segue 后无法关闭 OSX Cocoa 应用程序

c# - 你能在 C# 7 中命名元组签名吗?