In Swift, Can One Use a String to Access a Struct Property

In Swift, can one use a string to access a struct property?

I don't think string-based access like this is good Swift style. vadian shows how it can be done, but to dynamically get and set members like this, it would be best to use the built-in keypath functionality:

let redChannel = pixel[keyPath: \.red]
pixel[keyPath: \.green] = 0xB5

Another option (more relevant prior to Swift 4) would be to use an enum to define the keys:

enum Component
{
case red
case green
case blue
case alpha
}

Then adapt the subscript function that vadian demonstrated to accept Pixel.Component instead of String.

This has a significant advantage in that you can no longer pass an invalid key.

Based on your definition:

public extension Pixel
{
public enum Component
{
case red, blue, green, alpha
}

public subscript(key: Component) -> UInt8
{
get
{
switch key {
case .red: return self.red
case .green: return self.green
case .blue: return self.blue
case .alpha: return self.alpha
}
}
set
{
switch key {
case .red: self.red = newValue
case .green: self.green = newValue
case .blue: self.blue = newValue
case .alpha: self.alpha = newValue
}
}
}
}

var pxl = Pixel(value: 0xFEEDFACE, red: 0xFE, green: 0xED, blue: 0xFA, alpha: 0xCE)
let redChannel = pxl[.red]
print(redChannel)
pxl[.green] = 0xB5
print(pxl)

Dynamically access property of property of struct

I asked the same question (but better explained) in the swift forums and got a great answer from Alexis Schultz:

    func findContactId() -> String? {
Mirror(reflecting: self)
.children
.first(where: { $0.label == responseId })
.map(\.value)
.flatMap(Mirror.init(reflecting:))?
.children
.first(where: { $0.label == "some" })
.map(\.value)
.flatMap(Mirror.init(reflecting:))?
.children
.first(where: { $0.label == "contactId" })?
.value as? String
}

Later, after seeing word "some" I realized that Mirror's descendant function can do exactly the same job:

    func findContactId() -> String? {
let mirror = Mirror(reflecting: self)
let value = mirror.descendant(responseId, "some", "contactId") as? String
return value
}

how to acess Struct property by name as a string in runtime in swiftui

A straightforward way is to add a function to your struct that returns the right value for a given key.

func stringProperty(for path: String) -> String {
switch path {
case "abc":
return "\(abc)"
case "def":
return "\(def)"
case "ghi":
return "\(ghi)"
default:
fatalError("Unknown property name")
}
}

Get struct properties from string - swift

What you are looking for is reflection:

struct MyStruct {
var informationA = "test"
var informationB = "test...test"
var informationC = "test...test"
var informationD = "test...test..."
}

func getInformation() {
let my_struct = MyStruct()
let keys = ["informationA", "informationB", "informationC"]
let m = Mirror(reflecting: my_struct)
let properties = Array(m.children)

for k in keys {
if let prop = properties.first(where: { $0.label == k }) {
print(prop.value)
}
}
}

Access a struct property

First thing's first. Let's fix your struct names. struct declarations should be CapitalizedCamelCase, so your struct looks like this:

struct Categorie: Decodable{
let title: [String]
}
struct Business: Decodable {
let name: String = ""
let categories: [Categorie]
}

Next, you're looking for the title property of an element in the array of categories, so you'd do it like so:

business.categories[0].title

You need to specify which element of the array you want to examine. In the example above, I'm getting the 1st element's ([0]) title property. You'll want to put some logic in to protect against categories being empty.

Access data of of struct swift

Text(response!.choices[2])

This line returns a Choice struct which is not a string representable. You need to go a level deeper and access it's text property.

Text(response!.choices[2].text)

I assume you have hardcoded and forced unwrapped for the example's sake. Otherwise follow safe coding practices :)



Related Topics



Leave a reply



Submit