[swift-evolution] Optional safe subscripting for arrays

davesweeris at mac.com davesweeris at mac.com
Sat Jan 16 19:29:09 CST 2016


I’m definitely +1 on the getter. I have reservations on the setter. As described, this code:
subscript(safe index: Index) -> Element? {
    return self.indices ~= index ? self[index] : nil
}
subscript(clamp index: Index) -> Element? {
    get { return self.indices ~= index ? self[index] : nil } // again, because subscripts can’t be setter-only
    set {
        if self.indices ~= index {
            self[index] = newValue!
        } else {
            self.append(newValue!)
        }
    }
}

Would lead to some counter-intuitive results.
var foo = [0, 1, 2]
print(foo[safe: 2]) // Optional(2)… Yep
foo[clamp: 6] = 6
print(foo[safe: 6]) // nil… Wait, what? I just set that to 6! Why is it nil now?


Instead of just appending the new value, we could extend the array to the required capacity:
subscript(safe index: Index) -> Element? {
    get { return self.indices ~= index ? self[index] : nil }
    set {
        if self.indices ~= index {
            self[index] = newValue!
        } else {
            while !(self.indices ~= index) {
                self.append(newValue!)
            }
        }
    }
}

The results could still be unexpected:
var foo = [0, 1, 2]
print(foo) 		// [0, 1, 2]… Yep
foo[safe: 9] = 9
print(foo[safe: 9]) 	// Optional(9)… Yep
print(foo) 		// [0, 1, 2, 9, 9, 9, 9, 9, 9]… Wow, that’s bigger than I thought

but at least you’d be able to read from the index to which you just wrote.

- Dave Sweeris

> On Jan 16, 2016, at 14:08, Maximilian Hünenberger via swift-evolution <swift-evolution at swift.org> wrote:
> 
> I've also thought of this. But the concept of safe indexing can also be extended to CollectionType (or to the more abstract Indexable protocol) where it's index is Comparable.
> 
> For mutable Collections/MutableIndexable there could be two versions of a safe subscript set:
> 
> array[safe: 5] = 7 // does nothing if index out of bounds
> 
> array[clamp: 5] = 7
> // if array is empty: does nothing
> // if 5 >= array.endIndex : sets last element
> // if index < 0 : sets first index
> 
> So definitely worth considering.
> 
> 
> - Maximilian
> 
> Am 16.01.2016 um 21:44 schrieb Rudolf Adamkovič via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>>:
> 
>> Hi there!
>> 
>> From time to time, I find myself using safe subscripting, e.g.:
>> 
>> let array = [1, 2, 3]
>> 
>> array[safe: 0] // 1
>> array[safe: 1] // 2
>> array[safe: 2] // 3
>> array[safe: 3] // nil
>> 
>> … with the following implementation:
>> 
>> subscript (safe index: Int) -> Element? {
>>     return self.indices ~= index ? self[index] : nil
>> }
>> 
>> I was wondering … wouldn’t it be handy to have this in the standard library?
>> 
>> Best regards,
>> Rudolf Adamkovic
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160116/3e45a1be/attachment.html>


More information about the swift-evolution mailing list