'How to decode JSON array as property of struct with JSONDecoder

I had data struct like this

{
    "version": 1,
    "profile": [
        {
            "type": "name",
            "value": "Hellow"
        },
        {
            "type": "email",
            "value": "[email protected]"
        },
    ]
}

Now I could decode it like this

struct Profile: Decodable {
    let version: Int
    let name: String
    let email: String
    struct Item: Decodable {
        let type: String
        let value: String
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        version = try container.decode(Int.self, forKey: .version)
        let items = try container.decode([Item].self, forKey: .data)
        name = items.first{$0.type == "name"}!.value
        email = items.first{$0.type == "email"}!.value
    }
}

Does there are any way to update Profile without rewrite init(from)?

Update
@dynamicMemberLookup can use like mapping function. But it will lose autocomplete.

@dynamicMemberLookup
struct Profile: Decodable {
    let version: Int
    
    struct Item: Decodable {
        let type: Keys
        let value: String
    }
    let profile: [Item]
    
    enum Keys: String, Decodable, ExpressibleByStringLiteral {
        case name
        case email
        case undefined
        
        init(stringLiteral: String) {
            self = Keys(rawValue: stringLiteral) ?? .undefined
        }
    }
    
    subscript(dynamicMember member: Keys) -> String {
        return profile.first{$0.type == member}?.value ?? "undefined"
    }
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source