I am beginner with the Swift
having no advance knowledge with operators.
I have the following class
class Container {
var list: [Any]
It sounds like you are looking for subscripts. You can make subscripts for your own type like the following example:
class Container {
var list = [["Hello", "World"], ["Foo", "Bar"]]
subscript(index: Int) -> [String] {
get {
return list[index]
}
set {
list.insert(newValue, atIndex: index)
}
}
}
The above example works with the double [ ]
only because I know that we are going to return an Array
. Here the Array
contain Strings as an example, but you could of course swap in your own type
var container = Container()
container[0][0] = "Stack"
container[0][1] = "Overflow"
print(container[0][0]) // "Stack"
print(container[1][1]) // "Bar"
class Container {
private var list = [Any]()
subscript(_ index: Int) -> Int? {
get {
guard index < list.count else { return nil }
return list[index]
}
set(newValue){
guard let unwrappedElement = newValue else { return }
list.insert(unwrappedElement, at: index)
}
}
}
Here we are using subscripts with optional type to handle index out of range.
Static function with generic type
class Defaults {
static subscript<T>(key: DefaultsKey) -> T? {
get {
return UserDefaults.standard.value(forKey: key.rawValue) as? T
}
set {
UserDefaults.standard.set(newValue, forKey: key.rawValue)
}
}
}
enum DefaultsKey: String {
case firstKey = "JSGHDjasgchvsas"
}
Save value
Defaults[.firstKey] = 34
Get value
let value: Int = Defaults[.firstKey]
Happy coding!
A workaround is to leverage multiple parameters in subscript
So instead of data[1][2]
, you can say data[1, 2]
. This will be handy in some cases
struct Container {
subscript(a: Int, b: Int) -> String {
print(a)
print(b)
return "possible"
}
}
let data = Container()
data[1, 2]
It looks like there are 2 questions here.
subscripting
on my own custom class?To enable subscripting
on your class Container
you need to implement the subscript
computed property like this.
class Container {
private var list : [Any] = [] // I made this private
subscript(index:Int) -> Any {
get {
return list[index]
}
set(newElm) {
list.insert(newElm, atIndex: index)
}
}
}
Now you can use it this way.
var container = Container()
container[0] = "Star Trek"
container[1] = "Star Trek TNG"
container[2] = "Star Trek DS9"
container[3] = "Star Trek VOY"
container[1] // "Star Trek TNG"
Container
that supports subscripting writing something like data[1][2]
?If we use your example no, you cannot. Because data[1]
returns something of type Any
. And you cannot subscript Any
.
But if you add a cast it becomes possible
var container = Container()
container[0] = ["Enterprise", "Defiant", "Voyager"]
(container[0] as! [String])[2] // > "Voyager"
class Container
{
var list: [AnyObject] = ["hello" , "world"];
subscript ( i : Int) -> AnyObject{
get{
return list[i]
}
set{
list[i] = newValue
}
}
}
var c : Container = Container()
println(c[1])
c[1] = "lol"
println(c[1])
For more information about operator : http://nshipster.com/swift-operators/