kamisama42
kamisama42

Reputation: 625

Iterating through references to variables in Swift

I am looking for a way to change the values of multiple variables using iteration in Swift. An example would be something like this:

var a = false
var b = false
var c = false

func makeAllTrue() {
    for n in [a, b, c] {
        n = true
    }
}

...but rather than an array of values, I want to iterate through an array of pointers/references to the variables above.

Any advice would be greatly appreciated.

Upvotes: 1

Views: 594

Answers (3)

Sweeper
Sweeper

Reputation: 271410

It is possible to do this with key paths. Let's say the properties are in a class Foo:

class Foo {
    var a = false
    var b = false
    var c = false
    
    func makeAllTrue() {
        for n in [\Foo.a, \Foo.b, \Foo.c] {
            self[keyPath: n] = true
        }
    }
}

If Foo is a struct, use mutating func instead:

struct Foo {
    var a = false
    var b = false
    var c = false
    
    mutating func makeAllTrue() {
        for n in [\Foo.a, \Foo.b, \Foo.c] {
            self[keyPath: n] = true
        }
    }
}

However, if the class name is long, I don't think it is worth doing this way.

If these three properties are very related, I would not bother with the key path stuff and replace a, b and c with an array:

var abc = [false, false, false]

and have the for loop loop over the indices:

for i in abc.indices {
    abc[i] = true
}

Upvotes: 2

Aleksey Gotyanov
Aleksey Gotyanov

Reputation: 550

var a = false
var b = false
var c = false

mutateValues(&a, &b, &c) { n in
    n = true
}

print(a, b, c) // will be printed "true true true"

func mutateValues<Value>(_ values: UnsafeMutablePointer<Value>..., mutate: (inout Value) -> Void) {
    values.forEach {
        mutate(&$0.pointee)
    }
}

Upvotes: 2

YanivH
YanivH

Reputation: 591

An Array in Swift is a struct, hence a value type.

Iterating over his children, and changing one, will not be possible unless:

  • The type of child is aa class (which is reference typed)
  • You iterate over the indices and change the real values!
    • E.G:

      var a: Int = 1
      var b: Int = 2
      var array: [Int] = [a,b]
      
      for index in array.indices {
         array[index] += 1
      }
      
      print(array)      // [2,3]
      

Upvotes: 1

Related Questions