首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何将Swift JSON / Dict Key camel转换为下划线而不编码?

在Swift中,可以使用Codable协议和自定义编码器来将JSON或字典中的键从驼峰式转换为下划线式,而不进行编码。下面是一个完整的解决方案:

首先,我们需要创建一个自定义的KeyEncodingStrategy枚举,用于指定键的编码策略。在这种情况下,我们将使用.convertToSnakeCase选项,它将驼峰式键转换为下划线式键。

代码语言:txt
复制
enum KeyEncodingStrategy {
    case convertToSnakeCase

    func convert(_ key: String) -> String {
        switch self {
        case .convertToSnakeCase:
            return convertToSnakeCase(key)
        }
    }

    private func convertToSnakeCase(_ key: String) -> String {
        guard !key.isEmpty else { return key }

        var convertedKey = ""
        var wasUppercase = false

        for character in key {
            if character.isUppercase {
                if !convertedKey.isEmpty && !wasUppercase {
                    convertedKey.append("_")
                }
                wasUppercase = true
            } else {
                wasUppercase = false
            }
            convertedKey.append(character.lowercased())
        }

        return convertedKey
    }
}

接下来,我们可以创建一个自定义的KeyedCodingContainer,它将使用上述的编码策略来转换键。我们需要实现KeyedDecodingContainerProtocolKeyedEncodingContainerProtocol协议中的方法。

代码语言:txt
复制
struct KeyedCodingContainer<K: CodingKey>: KeyedDecodingContainerProtocol, KeyedEncodingContainerProtocol {
    typealias Key = K

    private let container: KeyedEncodingContainer<K>
    private let keyEncodingStrategy: KeyEncodingStrategy

    init(container: KeyedEncodingContainer<K>, keyEncodingStrategy: KeyEncodingStrategy) {
        self.container = container
        self.keyEncodingStrategy = keyEncodingStrategy
    }

    // KeyedDecodingContainerProtocol methods

    var codingPath: [CodingKey] {
        return container.codingPath
    }

    func contains(_ key: K) -> Bool {
        return container.contains(key)
    }

    func decodeNil(forKey key: K) throws -> Bool {
        return try container.decodeNil(forKey: key)
    }

    func decode<T: Decodable>(_ type: T.Type, forKey key: K) throws -> T {
        return try container.decode(type, forKey: key)
    }

    func nestedContainer<NestedKey: CodingKey>(keyedBy type: NestedKey.Type, forKey key: K) throws -> KeyedDecodingContainer<NestedKey> {
        return try container.nestedContainer(keyedBy: type, forKey: key)
    }

    func nestedUnkeyedContainer(forKey key: K) throws -> UnkeyedDecodingContainer {
        return try container.nestedUnkeyedContainer(forKey: key)
    }

    func superDecoder() throws -> Decoder {
        return try container.superDecoder()
    }

    func superDecoder(forKey key: K) throws -> Decoder {
        return try container.superDecoder(forKey: key)
    }

    // KeyedEncodingContainerProtocol methods

    mutating func encodeNil(forKey key: K) throws {
        try container.encodeNil(forKey: key)
    }

    mutating func encode<T: Encodable>(_ value: T, forKey key: K) throws {
        let convertedKey = keyEncodingStrategy.convert(key.stringValue)
        try container.encode(value, forKey: K(stringValue: convertedKey)!)
    }

    mutating func nestedContainer<NestedKey: CodingKey>(keyedBy keyType: NestedKey.Type, forKey key: K) -> KeyedEncodingContainer<NestedKey> {
        return container.nestedContainer(keyedBy: keyType, forKey: key)
    }

    mutating func nestedUnkeyedContainer(forKey key: K) -> UnkeyedEncodingContainer {
        return container.nestedUnkeyedContainer(forKey: key)
    }

    mutating func superEncoder() -> Encoder {
        return container.superEncoder()
    }

    mutating func superEncoder(forKey key: K) -> Encoder {
        return container.superEncoder(forKey: key)
    }
}

现在,我们可以创建一个自定义的JSONEncoder子类,它将使用上述的KeyedCodingContainer来进行编码。

代码语言:txt
复制
class SnakeCaseJSONEncoder: JSONEncoder {
    override func encode<T>(_ value: T) throws -> Data where T : Encodable {
        userInfo[.keyEncodingStrategy] = KeyEncodingStrategy.convertToSnakeCase
        return try super.encode(value)
    }

    override func container<Key>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> where Key : CodingKey {
        let container = super.container(keyedBy: type)
        let keyEncodingStrategy = userInfo[.keyEncodingStrategy] as? KeyEncodingStrategy ?? .useDefaultKeys
        return KeyedEncodingContainer(KeyedCodingContainer(container: container, keyEncodingStrategy: keyEncodingStrategy))
    }
}

最后,我们可以使用SnakeCaseJSONEncoder来将Swift对象编码为JSON字符串,并将驼峰式键转换为下划线式键。

代码语言:txt
复制
struct Person: Codable {
    let firstName: String
    let lastName: String
    let age: Int
}

let person = Person(firstName: "John", lastName: "Doe", age: 30)

let encoder = SnakeCaseJSONEncoder()
encoder.outputFormatting = .prettyPrinted

do {
    let jsonData = try encoder.encode(person)
    if let jsonString = String(data: jsonData, encoding: .utf8) {
        print(jsonString)
    }
} catch {
    print(error)
}

这样,我们就可以将Swift中的JSON或字典键从驼峰式转换为下划线式,而不进行编码。请注意,这只是一个示例解决方案,您可以根据自己的需求进行修改和扩展。

腾讯云相关产品和产品介绍链接地址:

  • 腾讯云产品:https://cloud.tencent.com/product
  • 云服务器(CVM):https://cloud.tencent.com/product/cvm
  • 云数据库 MySQL 版:https://cloud.tencent.com/product/cdb-for-mysql
  • 云原生应用引擎(TKE):https://cloud.tencent.com/product/tke
  • 云存储(COS):https://cloud.tencent.com/product/cos
  • 人工智能平台(AI):https://cloud.tencent.com/product/ai
  • 物联网(IoT):https://cloud.tencent.com/product/iotexplorer
  • 移动开发(移动推送):https://cloud.tencent.com/product/umeng
  • 区块链(BCS):https://cloud.tencent.com/product/bcs
  • 元宇宙(QTS):https://cloud.tencent.com/product/qts
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • Python3使用过程中需要注意的点

    ASCII、Unicode、UTF-8、GBK 区别 python2内容进行编码(默认ASCII),python3对内容进行编码的默认为UTF-8。...=None):返回指定键的值,如果值不在字典中返回default值 key in dict:如果键在字典dict里返回true,否则返回false radiansdict.items():以列表返回可遍历的...(键, 值) 元组数组 radiansdict.keys():返回一个迭代器,可以使用 list() 来转换为列表 radiansdict.setdefault(key, default=None):和...():返回一个迭代器,可以使用 list() 来转换为列表 pop(key[,default]):删除字典给定键 key 所对应的值,返回值为被删除的值。...闭包作用 被引用的变量被称为自由变量,不会随着函数的结束消失,保证数据安全。

    1.6K50

    OC最实用的runtime总结,面试、工作你看我就足够了!前言什么是runtime?如何应用运行时?

    案例3:利用runtime 获取所有属性来进行字典模型 以往我们都是利用KVC进行字典模型,但是它还是有一定的局限性,例如:模型属性和键值对对应上会crash(虽然可以重写setValue:forUndefinedKey...JSON数据 - (void)setDict:(NSDictionary *)dict { Class c = self.class; while (c &&c !...JSON数据 这时候我们就需要利用runtime的ivar_getTypeEncoding 方法获取模型对象类型,对该模型对象类型再进行字典模型,也就是进行递归,需要注意的是我们要排除系统的对象类型,...[type hasPrefix:@"NS"]) { // 将对象名转换为对象的类型,将新的对象字典模型(递归) Class...[type hasPrefix:@"NS"]) { // 将对象名转换为对象的类型,将新的对象字典模型(递归) Class

    1.3K120

    OC史上最实用的runtime总结,面试、工作你看我就足够了

    案例3:利用runtime 获取所有属性来进行字典模型 以往我们都是利用KVC进行字典模型,但是它还是有一定的局限性,例如:模型属性和键值对对应上会crash(虽然可以重写setValue:forUndefinedKey...数据和sample如下: JSON数据 - (void)setDict:(NSDictionary *)dict { Class c = self.class; while (c &&c !...:1]; // 取出字典的值 id value = dict[key]; // 如果模型属性数量大于字典键值对数理,模型属性会被赋值为nil报错 if (value == nil) continue...:1]; // 取出字典的值 id value = dict[key]; // 如果模型属性数量大于字典键值对数理,模型属性会被赋值为nil报错 if (value == nil) continue...:1]; // 取出字典的值 id value = dict[key]; // 如果模型属性数量大于字典键值对数理,模型属性会被赋值为nil报错 if (value == nil) continue

    1.5K20

    Python request使用方法及问题总结

    2.不管是那种格式的入参,data入参格式都是{“key”:“vaue”,“key1”:“vaue1″},注意参数最好用 ” 不是 ‘ 。...False); 4.参数headers必须为字典类型,字符字典方法如下:json.loads(headers),判断是否是字典方法如:isinstance(data,dict) 模拟post方式访问...2.不管是那种格式的入参,data入参格式都是{“key”:“vaue”,“key1”:“vaue1″},注意参数最好用 ” 不是 ‘ 。...,字符个数不是key-value个数,或者key-vaule用的是单引号,如json.loads(‘key’:’value’) 解决方案: 1.响应内容必须是json格式才可以调用josn字典json...()方法 2.json格式入参,如res = requests.post(url, data=data, headers = headers),入参data值必须转换为字符类型 3.字符字典,必须保证是

    1.8K10

    idea插件

    也避免了测试提的bug多影响个人绩效(有些公司把bug计入考核范围内)。...,可对整个项目或单个文件进行编码规约扫描,快捷键"Ctrl+Alt+Shift+J"。...CamelCase图片介绍:字符串格式转换工具安装之后在设置中找到"Camel Case"选项,选择需要转换的格式,本人只保留了驼峰和下划线两种格式。如需使用多种格式,下方还可对格式顺序进行调整。...图片GsonFormatPlus图片介绍:JSON实体类插件安装之后在JAVA类中使用快捷键Alt+Insert,选择"GsonFormatPlus",在弹出的窗口中输入JSON数据并识别,选择JAVA...图片GenerateAllSetter当你进行对象之间赋值的时候,你会发现好麻烦呀,能不能有一个更好的办法呢~ 有,只要你选中需要生成set方法的对象,按下快捷键 alt+enter 界面如下:图片Key

    72510

    Python3 编程笔记

    函数或者变量带下划线的意义 变量: 前带 _ 的变量: 标明是一个私有变量, 只用于标明, 外部类还是可以访问到这个变量 前带两个 _ ,后带两个 _ 的变量: 标明是内置变量, 大写加下划线的变量:...OrderedDict 可以实现一个 FIFO(先进先出)的 dict,当容量超出限制时,先删除最早添加的 Key。...判断键是否存在于字典中 if key in dict():通过 in 判断 key 是否存在 dict.get(key, value):是通过 dict 提供的 get 方法,如果 key 不存在,可以返回...和可变参数类似,也可以先组装出一个 dict,然后,把该 dict换为关键字参数传进去。...数据解析 json.dumps(): 对数据进行编码 json.loads(): 对数据进行解码 如果要处理的是文件不是字符串,你可以使用 json.dump() 和 json.load() 来编码和解码

    86510

    Swift基础语法(一)

    Swift中,语句结束可以不加分号。但是如果同一行有多个语句,仍然要加分号,不过我们建议一行多句,我们提倡一行一句的代码风格。...字典 字典是由键值对(key:value)组成的集合,它由两部分集合构成:一个是键集合,一个是值集合。字典是通过访问键来间接访问值的,键集合中是不可以有重复元素的,值集合中的元素是可以重复的。...,如果Key值不存在,那么就是添加元素; * 如果Key值存在,那么就是修改元素 */ //删除元素 dict.removeValue(forKey: "age") // 删除指定元素 dict.removeAll..."male"] //遍历字典中所有的Value值 for value in dict.values { print(value) } //遍历字典中所有的Key值 for key in dict.keys...: [String : Any] = ["height" : 178, "weight" : 65] for (key, value) in dict2 { dict1[key] = value

    4.3K30

    洞悉客户心声:Pandas标签帮你透视客户,标签化营销如虎添翼

    进行原地修改,即创建新的副本 df[key].fillna(cat_val['其他'], inplace=True) # 将数据类型转换为int64 df[...将指标转换为标签编码有几个好处:简化解释: 标签编码将原本复杂的数值转换为了易于理解的分类标签,使得数据解释更加直观和简单。...降低误差: 通过将连续的数值转换为有限的分类,可以降低由于数据误差或测量不准确性引起的影响。...增强模型泛化能力: 在某些机器学习模型中,将指标转换为标签编码可以提高模型的泛化能力,使其更适应不同的数据分布和模式。方便数据分析: 标签编码使得数据更容易被聚合和比较,从而方便进行数据分析和可视化。...Python 对象 字典值 print(cat_dict)运行结果{'curr_hold_amt_mom': -2, 'curr_hold_amt_yoy': -2}五、pandas横表竖表最后这段代码的主要作用是将数据从横表转换为竖表

    18510

    Swift基础语法简化版

    字典 字典是由键值对(key:value)组成的集合,它由两部分集合构成:一个是键集合,一个是值集合。字典是通过访问键来间接访问值的,键集合中是不可以有重复元素的,值集合中的元素是可以重复的。...,如果Key值不存在,那么就是添加元素; * 如果Key值存在,那么就是修改元素 */ //删除元素 dict.removeValue(forKey: "age") // 删除指定元素 dict.removeAll..."male"] //遍历字典中所有的Value值 for value in dict.values { print(value) } //遍历字典中所有的Key值 for key in dict.keys...{ print(key) } //遍历所有的键值对 for (key, value) in dict { print(key) print(value) } 字典的合并 前面讲的字符串和数组...: [String : Any] = ["height" : 178, "weight" : 65]for (key, value) in dict2 { dict1[key] = value}

    3.8K50

    idea插件.md

    也避免了测试提的bug多影响个人绩效(有些公司把bug计入考核范围内)。...安装之后右键菜单会多出两个选项,可对整个项目或单个文件进行编码规约扫描,快捷键"Ctrl+Alt+Shift+J"。...CamelCase 介绍:字符串格式转换工具 安装之后在设置中找到"Camel Case"选项,选择需要转换的格式,本人只保留了驼峰和下划线两种格式。如需使用多种格式,下方还可对格式顺序进行调整。...GsonFormatPlus 介绍:JSON实体类插件 安装之后在JAVA类中使用快捷键Alt+Insert,选择"GsonFormatPlus",在弹出的窗口中输入JSON数据并识别,选择JAVA...GenerateAllSetter 当你进行对象之间赋值的时候,你会发现好麻烦呀,能不能有一个更好的办法呢~ 有,只要你选中需要生成set方法的对象,按下快捷键 alt+enter 界面如下: Key

    1K20
    领券