如何迭代元组数组中的单个元组项

Mas*_*ver 1 arrays tuples swift

我有一组Int, CustomType, OtherCustomType. 数组按元组的 Int 部分排序。

为了在正确的位置添加新元素,我编写了一个二分搜索函数来获取插入点索引。

该函数返回一个新的 元组Int, Bool,其中 Bool 表示该元素是否已经存在,而 Int 是新元素第一次出现的索引,或者是大于新元素的第一个元素的索引。

该函数是通用编写的,并采用可比较类型的数组和相同类型的新元素作为参数,因此,显然,我不能简单地传递我的元组数组。

一个简单的解决方案是重新组织我的数据,而不是将三个值作为元组存储在一个数组中,我可以使用三个单独的数组,每个数组只包含三个值中的一个。然后我将只将第一个数组传递给二分搜索函数,然后在找到的索引处对所有三个数组执行所需的操作。

但是有没有办法让我的数据组织成元组,并且只将每个元组的一个元素传递给函数,就像我们能够在比较中忽略元组的一部分一样if tuple == (_ ,23, _)

下面是一些示例代码:

func findInsertPoint <T: Comparable> (forElement: T, inArray: [T]) -> (Int, Bool) {
    var low = 0
    var high = inArray.count

    if forElement > inArray[high-1] {
        return (high, false)
    }
    while low < high {
        let mid = (low+high)/2
        if inArray[mid] >= forElement {
            high = mid
        } else {
            low = mid+1
        }
    }
    return(low,(inArray[low] == forElement))
}
Run Code Online (Sandbox Code Playgroud)

一组 Int 工作得很好:

// index         0 1 2 3 4 5  6  7  8  9  10 11 12 13 14 15
var testArray = [1,2,5,7,8,11,12,12,12,15,19,22,22,26,52,56]

findInsertPoint(forElement: x, inArray: testArray)

// x = 17 returns (10,false)
// x = 19 returns (10,true)
Run Code Online (Sandbox Code Playgroud)

但我的实际数组看起来像这样:

var testArray = [(4,"Bee",2.5),(5,"dog",1.0),(8,"dog",43.13)]
Run Code Online (Sandbox Code Playgroud)

我如何只传递每个元组的第一部分的数组,但又不会在每个函数调用中昂贵地创建一个实际的新数组?

一种可能性是调用该函数:

findInsertPoint(forElement: 7 in Array: testArray.0)
Run Code Online (Sandbox Code Playgroud)

这将是完美的,但我知道这行不通。

对于只接受单一类型数组的函数调用,是否有一种 Swift 方法可以暂时忽略元组或结构的成员?

如果没有,我知道我的两种可能性是:

  1. 坚持我的 taylored 二分搜索,而不是上面代码中的通用搜索。
  2. 将元组分成 3 个单独的数组。

Mas*_*ver 5

这是我找到的解决方案:

如果您有一个本身就是集合类型的类型数组,并且您只想查看外部数组每个成员的某个属性,请使用 swift 集合类型的 .map 方法:

var testArray = [(4,"Bee",2.5),(5,"dog",1.0),(8,"dog",43.13)]
var onlyFirstProperty = testArray.map({$0.0}) // [4,5,8]
Run Code Online (Sandbox Code Playgroud)

这样你会得到一个新数组,它只包含每个元组的第一个元素。$0.0 是 firstMember.firstProperty 的简写语法。在我的代码中,我可以这样调用我的函数:

findInsertPoint(forElement: 7 in Array: testArray.map({$0.0}))
Run Code Online (Sandbox Code Playgroud)