【问题标题】:How best to manage an array of optionals in Swift?如何最好地管理 Swift 中的一系列选项?
【发布时间】:2017-06-16 00:56:14
【问题描述】:

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

用 nil 初始化为某个常数大小(为了简洁起见,将使用泛型类型 T):

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

所以我们有:[nil, 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。

所以我对你们所有人的问题是,你们能找到更好或更“迅速”的方法来完成此任务吗?你觉得这个解决方案怎么样?您能否推荐一种不同的方法,或者您是否有任何关于语言这方面的信息丰富的 cmets 可以帮助我更清楚地理解这个过程?

【问题讨论】:

    标签: ios arrays swift optional


    【解决方案1】:
    • 现有的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)
        }
    }
    

    【讨论】:

    • 你甚至可以进行二分搜索。
    • @zneak:是的,但是如果您通过二分搜索找到 some nil 条目,那么您仍然需要找到 first nil 条目。
    • 是的,你必须比较对而不是单个元素,检查 N 是否为 nil 但 N-1 不是。
    猜你喜欢
    • 2021-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-27
    • 2011-10-27
    • 2017-06-25
    • 1970-01-01
    相关资源
    最近更新 更多