swift - 迭代元组数组中的单个元组项

时间:2017-07-06 16:32:58

标签: arrays swift tuples

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

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

该函数返回一个新的元组(Int,Bool),其中Bool告诉该元素是否已经存在,而Int是新元素第一次出现的索引,或者是第一个元素的索引。比新元素。

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

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

但是有没有办法将我的数据组织为元组并且只将每个元组的一个元素传递给函数,就像我们能够在比较中忽略元组的一部分,比如“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))
}

一系列Ints工作得很好:

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

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

var testArray = [(4,"Bee",2.5),(5,"dog",1.0),(8,"dog",43.13)]

我正在寻找一种方法来传递每个元组的第一部分的数组,但是没有为每个函数调用创建一个实际的新数组。

所以,有可能像这样调用函数......

findInsertPoint(forElement: 7 in Array: testArray.0)

......会很完美,但我知道这不起作用。

所以,TL; DR:对于只接受单一类型数组的函数调用,是否有一种快速的方法来暂时忽略元组或结构的成员?

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

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

2 个答案:

答案 0 :(得分:2)

这是我找到的解决方案:

如果您有一个类型的数组,它们自己是集合类型,并且您只想查看外部数组的每个成员的某个属性,请使用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]

通过这种方式,您将获得一个新数组,该数组仅包含每个元组的第一个元素。 $ 0.0是firstMember.firstProperty的简写语法。在我的代码中,我可以像这样调用我的函数:

findInsertPoint(forElement: 7 in Array: testArray.map({$0.0}))

答案 1 :(得分:0)

您可以创建一个结构并在其中实现Comparable协议:

struct Foo: Comparable {
    let a: Int
    let b: TypeB
    let c: TypeC

    // compare according to the integers
    static func ==(lhs: Foo, rhs: Foo) -> Bool {
        return lhs.a == rhs.a
    }

    static func <(lhs: Foo, rhs: Foo) -> Bool {
        return lhs.a < rhs.a
    }
}

使用此结构,您可以使用所需结果调用自定义通用排序函数,如下所示:

let foos = [Foo]()
let (position, exists) = customSort(foos)

由于您的自定义排序函数使用了类似的协议,因此它应该与struct结合使用。