How to loop over struct properties in Swift?

前端 未结 6 1089
情话喂你
情话喂你 2020-12-13 04:16

Is it possible to iterate over properties of a struct in Swift?

I need to register cells-reuse identifiers in a view controller that makes use of many different cel

6条回答
  •  清歌不尽
    2020-12-13 05:04

    I made a recursive function based on @John R Perry's solution that goes deeper into properties that are objects. It also takes an parameter to limit how many levels deep it goes (default is Int.max) to help prevent stackoverflow's:

    protocol Loopable {
        func allProperties(limit: Int) [String: Any]
    }
    
    extension Loopable {
        func allProperties(limit: Int = Int.max) [String: Any] {
            return props(obj: self, count: 0, limit: limit)
        }
    
        private func props(obj: Any, count: Int, limit: Int) -> [String: Any] {
            let mirror = Mirror(reflecting: obj)
            var result: [String: Any] = [:]
            for (prop, val) in mirror.children {
                guard let prop = prop else { continue }
                if limit == count {
                    result[prop] = val
                } else {
                    let subResult = props(obj: val, count: count + 1, limit: limit)
                    result[prop] = subResult.count == 0 ? val : subResult
                }
            }
            return result
        }
    }
    

    I got rid of the check for if the object is a class or struct because that the parameter not being a class or struct is the base case of the recursive function, and it was easier to handle it manually than with errors.

    Testing it:

    class C {
        var w = 14
    }
    class B: Loopable {
        var x = 12
        var y = "BHello"
        var z = C()
        static func test() -> String {
            return "Test"
        }
    }
    class A: Loopable {
        var a = 1
        var c = 10.0
        var d = "AHello"
        var e = true
        var f = B()
        var g = [1,2,3,4]
        var h: [String: Any] = ["A": 0, "B": "Dictionary"]
        var i: Int?
    }
    print(A().allProperties())
    

    prints:

    ["e": true, "g": [1, 2, 3, 4], "f": ["z": ["w": 14], "x": 12, "y": "BHello"], "h": ["A": 0, "B": "Dictionary"], "c": 10.0, "i": nil, "d": "AHello", "a": 1]
    

    (Dictionaries are unordered, so if you get a different order, that's why)

提交回复
热议问题