Access tuples by subscript
What you want is not possible with tuples and if you dont want to cast everything later-on your only option is struct or class. struct seems like a better choise :)
struct MyStruct {
let opt1 = 0
let opt2 = 0
let opt3 = 0
...
let boolThing = false
}
Can a Swift subscript implementation set a tuple value?
Yes, a subscript method can have a tuple type.
First, you have defined the subscript
value as an optional(Foo, Bar)?
, so newValue
needs to be unwrapped. (And you have to
decide what to do if newValue
is nil
.)
Second, if you want
to access the tuple member by names .foo/.bar
, you have to define a named tuple:
subscript(index: Int) -> (foo: Foo, bar: Bar)? {
// ...
set(newValue) {
if let value = newValue {
foos[index] = value.foo
bars[index] = value.bar
}
}
}
Alternatively, access the tuple members with value.0
and value.1
.
Why can we not access elements of a tuple by index?
Because [] is an operator (named operator[]
), thus a member function, and is called at run-time.
Whereas getting the tuple item is a template mechanism, it must be resolved at compile time. Which means this can be only done with the <> templating syntax.
To better understand, a tuple may store different types. A template function may return different types depending on the index passed, as this is resolved at compile time.
The operator[] must return a unique type, whatever the value of the passed parameter is. Thus the tuple functionality is not achievable.
get<0>(x)
and get<1>(x)
are two different functions generated at compile time, and return different types. The compiler generates in fact two functions which will be mangled to something like
int get_tuple_int_string_int_0(x)
and
string get_tuple_int_string_int_1(x)
Subscript tuple-unpacking notation in comprehensions
No, you cannot slice an unpacking operation.
There are various possible workarounds though:
If the iterable you're unpacking can be sliced, just slice it directly. For example, to get the 3rd element of a
range
:>>> [*range(4)[2:3]]
[2]So why are we using
[2:3]
here? It's simple:range(4)[2]
would return a single integer, and integers can't be unpacked:>>> [*range(4)[2]]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterableBut
range(4)[2:3]
returns a single-element list, so the unpacking succeeds.If the iterable can't be sliced, slice it anyway by using
itertools.islice
:>>> [*itertools.islice(zip([1, 2, 3], [4, 5, 6]), 2, 3)]
[(3, 6)]If you only want a single element of a slice-able iterable, just don't unpack the iterable at all:
>>> [range(4)[2]]
[2]
Swift: Get an element from a tuple
According to the documentation (scroll down to Tuples), there are three ways to do it.
Given
var answer: (number: Int, good: Bool) = (100, true)
Method 1
Put the element variable name within a tuple.
let (firstElement, _) = answer
let (_, secondElement) = answer
or
let (firstElement, secondElement) = answer
Method 2
Use the index.
let firstElement = answer.0
let secondElement = answer.1
Method 3
Use the names. This only works, of course, if the elements were named in the Tuple declaration.
let firstElement = answer.number
let secondElement = answer.good
How to access a field of a namedtuple using a variable for the field name?
You can use getattr
getattr(my_car, field)
Related Topics
iOS 13 Modals - Calling Swipe Dismissal Programmatically
Callback Url Not Approved Despite Being Provided Twitter API
Using Custom Cifilter on Calayer Shows No Change to Calayer
Icloud Drive Issue: "[Documentmanager] Failed to Associate Thumbnails for Picked Url"
Building for Arm64E on Apple Silicon
Symbol Is Considered to Be an Identifier, Not an Operator
Nskeyedunarchiver Fails to Decode a Custom Object in Swift
Can Nscoding and Codable Co-Exist
Xctestcase Optional Instance Variable
Not Getting Expected Delegate Calls When Trying to Restore In-App Purchases with Storekit
Updating Fetchedresultscontroller for Predicate Set by Uisearchbar
Workarounds for Generic Variable in Swift
How to Make JSON Data Persistent for Offline Use (Swift 4)
What Does "Constrain to Margins" Mean in Interface Builder in Xcode 6.0.1
What Does a "Do Statement" Without Catch Block Mean
Nsurlsessiondatadelegate Method Didreceivedata and Others Are Not Called