Заставить все ключи атрибутов и значения быстрого класса в нижнем регистре

Мне нужно преобразовать все ключи и их значения класса в нижний регистр. Например,

class Person : Encodable {
    var firstName: String
    var lastName: String
     var city: String
}

 var person = Person(firstName: "David", lastName: "Gill", city: 
 "Toronto")
 let encoder = JSONEncoder()
 encoder.keyEncodingStrategy = .convertToLowerCase
 let encoded = try encoder.encode(person)
 print(String(decoding: encoded, as: UTF8.self))

Где convertToLowerCase — это метод, который я добавил в расширение JSONEncoder.KeyEncodingStrategy для преобразования ключей в нижний регистр.

Он печатает - {"city":"Toronto","firstname":"David","lastname":"Gill"}

Мне нужно распечатать - {"city":"toronto","firstname":"david","lastname":"gill"}

Может кто-нибудь помочь здесь?


person NChoudhary    schedule 23.04.2019    source источник
comment
это -key-EncodingStrategy не -value-EncodingStrategy   -  person Sh_Khan    schedule 23.04.2019
comment
Да, но есть ли другой способ преобразовать значения в нижний регистр? Я хочу преобразовать все значения за один раз, так как в реальном коде у меня много атрибутов в классе.   -  person NChoudhary    schedule 23.04.2019


Ответы (3)


Как это:

struct Person : Codable {
    var firstName: String
    var lastName: String
    var city: String
    enum CodingKeys : String, CodingKey {
        case firstName = "firstname"
        case lastName = "lastname"
        case city
    }
    func encode(to encoder: Encoder) throws {
        var con = encoder.container(keyedBy: CodingKeys.self)
        try! con.encode(self.firstName.lowercased(), forKey: .firstName)
        try! con.encode(self.lastName.lowercased(), forKey: .lastName)
        try! con.encode(self.city.lowercased(), forKey: .city)
    }
}

Тестирование:

let person = Person(firstName: "David", lastName: "Gill", city:
    "Toronto")
let encoder = JSONEncoder()
let encoded = try encoder.encode(person)
print(String(decoding: encoded, as: UTF8.self))
// {"firstname":"david","lastname":"gill","city":"toronto"}

Вы, вероятно, можете включить свой .convertToLowerCase, чтобы сэкономить часть работы.

person matt    schedule 23.04.2019

Вы можете сначала преобразовать каждое значение:

var firstName = "David"
var lastName = "Gill"
var city = "Toronto"

var editedFirst = firstName.lowercased()
var editedLast = lastName.lowercased()
var editedCity = city.lowercased()

 var person = Person(firstName: editedFirst, lastName: editedLast, city: 
 editedCity)

 let encoder = JSONEncoder()
 encoder.keyEncodingStrategy = .convertToLowerCase
 let encoded = try encoder.encode(person)
 print(String(decoding: encoded, as: UTF8.self))

Это не позволяет вам преобразовать все атрибуты объекта за один раз, но ваши значения будут преобразованы вместе с ключами.

Что касается вашего вопроса о том, можем ли мы перебрать это для каждого атрибута в классе: как насчет добавления версии каждого атрибута в нижнем регистре в класс?

Что-то вроде этого:

class Person : Encodable {
    var firstName: String
    var lastName: String
     var city: String

  let editedFirst = firstName.lowercased()
  let editedLast = lastName.lowercased()
  let editedCity = city.lowercased()
}

И тогда вы можете получить доступ к этому значению в нижнем регистре, когда вам нужно.

person Levi Yoder    schedule 23.04.2019
comment
Да, это требует большого изменения кода, так как у меня много атрибутов в классе. Можем ли мы перебрать это в нижнем регистре для каждого атрибута? - person NChoudhary; 23.04.2019
comment
Возможно, вы могли бы добавить каждое значение в нижнем регистре в класс для использования в любое время. Я привел пример только что выше. - person Levi Yoder; 23.04.2019
comment
Понятно. Спасибо. - person NChoudhary; 24.04.2019

Это не идеальный ответ, но он слишком длинный, чтобы вводить комментарий.

но вот что я бы попробовал:

  1. Преобразуйте свой объект в словарь (что-то вроде этого https://stackoverflow.com/a/46049763/503527)

  2. Сопоставьте значения словаря в нижнем регистре (это хороший ответ для сопоставления значений словаря https://stackoverflow.com/a/24219069/503527)

  3. Когда у вас есть сопоставленный словарь, JSONencode, и у вас должно быть то, что вам нужно.

person Nitin Alabur    schedule 23.04.2019
comment
Спасибо за наводки. - person NChoudhary; 24.04.2019
comment
@ Ответ Мэтта определенно лучше :) - person Nitin Alabur; 24.04.2019