我正在寻找管理一系列可选项并实现以下行为:
使用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。
所以我对你们所有人的问题是,你能看到一种更好或更“快捷”的方式来实现这一目标吗?您如何看待这个解决方案?您能否推荐一种不同的方法,或者您是否只是对该语言的这方面有任何信息性的评论,这将有助于我更清楚地理解这一过程?
答案 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)
}
}