-2

In swift 3.0, I would like to concatenate strings (string1 & string2) and use the resulting string (string3) as the name of the array I want to access.

let fruitsArray = ["apple", "orange", "banana"]
let appleArray = ["red", "green", "yellow"]

let string1 = "apple"
let string2 = "Array"
let string3 = string1 + string2

let string4 = string3[1]

Of course there is an error message "subscript is unavailable ...) What is the proper way to do this? Many thanks to you all.

2 Answers2

0

What you want is possible using some form of introspection but it's a bad practice and extremely clumsy anyhow. You should remodel your data, for example, use a Dictionary:

let data = [
    "fruitsArray" : ["apple", "orange", "banana"],
    "appleArray": ["red", "green", "yellow"]
]

let string1 = "apple"
let string2 = "Array"
let string3 = string1 + string2

if let array = data[string3] {
    let string4 = array[1]
    print(string4)
} else {
    print("Key not found")
}
Code Different
  • 90,614
  • 16
  • 144
  • 163
  • Yes, I understand this method, thank you. But is there a way to do it without a dictionary ? – Benoit Houde Nov 19 '16 at 15:45
  • Any other methods require you to wrap `fruitArray` and `appleArray` in a class or struct. If your wrapper class inherits from `NSObject`, you can use [`value(forKey: )`](https://developer.apple.com/reference/objectivec/nsobject/1412591-value). If you want a pure-Swift solution, take a look at [reflection](http://nshipster.com/mirrortype/) – Code Different Nov 19 '16 at 15:54
  • OK. Thank you very much. – Benoit Houde Nov 19 '16 at 15:58
0

As @CodeDifferent writes in his/her answer, you might want to consider remodelling your data as this type of runtime property accessing is not very "Swifty".

If you're only interesting in reading data for the sake of debugging, however, you could make use of the Mirror structure to perform runtime introspection on the data type that owns the array properties.

E.g.:

struct Foo {
    let fruitsArray = ["apple", "orange", "banana"]
    let appleArray = ["red", "green", "yellow"]
}

func attemptToReadStringArrayProperty(_ name: String, fromFoo foo: Foo) -> [String]? {
    return Mirror(reflecting: foo).children
        .flatMap { ($0 ?? name + ".") == name ? ($1 as? [String]) : nil }.first
}

/* example usage/debugging */
let string1 = "apple"
let string2 = "Array"
let string3 = string1 + string2
let foo = Foo()

if let strArr = attemptToReadStringArrayProperty(string3, fromFoo: foo) {
    strArr.forEach { print($0) }
} /* red
     green
     yellow */

Naturally, you could apply this approach for non-debugging purposes, but I wouldn't recommend it.

Community
  • 1
  • 1
dfrib
  • 70,367
  • 12
  • 127
  • 192