如何最好地管理Swift中的一系列选项?

时间:2017-06-16 00:56:14

标签: ios arrays swift optional

我正在寻找管理一系列可选项并实现以下行为:

使用nil初始化为某个常量(为简洁起见,使用泛型类型T):

var myRay = [T?](repeating: nil, count: 5)

所以我们有:[nil,nil,nil,nil,nil]

我想要一个函数从一开始就向这个数组添加项目,直接替换nil值。在数组填充非零值后,该函数只会将值添加到数组的末尾。

因此,如果我们在上面的数组上调用此函数7次,它将如下所示:

insert(item: T, array: inout [T]?)

x1: [X, nil, nil, nil, nil]
x2: [X, X, nil, nil, nil]
x3: [X, X, X, nil, nil]
x4: [X, X, X, X, nil]
x5: [X, X, X, X, X]
x6: [X, X, X, X, X, X]
x7: [X, X, X, X, X, X, X]  

(其中X是非零值)

我提出了以下解决方案可行。我把它扔到那里因为我认为可能有一个更好的解决方案,而且我认为这是一个非常有趣的问题,它出现在像swift这样的语言中,有选择性。在下面发布我的解决方案:

private func insertValue<T>(element: T, array: inout [T?]) {
    let insertIndex = getFirstNilIndex(fromArray: array)
    array.insert(element, at: insertIndex)

    if let lastElement = array.last, let _ = lastElement {
        // the last element is a non-nil value of type T
    } else {
        // the last element is nil
        array.remove(at: array.endIndex - 1)
    }
}

// returns index of first nil object in array, or the end index if the array does not contain any nil values
private func getFirstNilIndex<T>(fromArray array: [T?]) -> Int {
    for (index, item) in array.enumerated() {
        if item == nil {
            return index
        }
    }
    return array.endIndex
}

这是因为一种奇怪的情况,我们有一个双重包装的可选项。 Array.last返回一个可选项,当它返回的非零值本身是可选的时,你必须重新打开该值!我不认为这会起作用,因为我不知道Swift是否会区分.some(.none)和.none。

所以我对你们所有人的问题是,你能看到一种更好或更“快捷”的方式来实现这一目标吗?您如何看待这个解决方案?您能否推荐一种不同的方法,或者您是否只是对该语言的这方面有任何信息性的评论,这将有助于我更清楚地理解这一过程?

1 个答案:

答案 0 :(得分:4)

  • 现有的index(where:)方法可用于查找第一个nil条目的索引。
  • 如果找到nil元素,则替换条目,否则 附上一个条目。

这比总是插入新条目然后检查更简单 如果应删除最后一个元素。

func insertValue<T>(element: T, array: inout [T?]) {

    if let idx = array.index(where: { $0 == nil } ) {
        array[idx] = element
    } else {
        array.append(element)
    }
}