是否有一个 swift 库可以让您自定义 JSON 中键的顺序?
Posted
技术标签:
【中文标题】是否有一个 swift 库可以让您自定义 JSON 中键的顺序?【英文标题】:Is there a library for swift that lets you custom the order of the keys in a JSON? 【发布时间】:2020-01-21 07:38:09 【问题描述】:我有以下情况:
struct RequestCommand: Codable
var event: String
var uuid: String
var type: String
var data: [String]
var data = try! JSONEncoder().encode(RequestCommand(event: "click", uuid: "123456", type: "Button", data: ["A", "B", "C"]))
print(String(data: data, encoding: String.Encoding.utf8)!)
打印语句的结果如下:
"data": [
"A",
"B",
"C"
],
"event": "click",
"type": "Button",
"uuid": "123456"
如您所见,JSON 中键的顺序与 RequestCommand 中的字段不同。 我知道 JSONEncoder 不能保证顺序,而且使用 .sortedKeys 对我也不起作用,因为我必须保持 RequestCommand 中字段的确切顺序并且我不能重命名它们。 我的问题是,swift 中是否有一个库可以让我选择与 JSON 中的 swift 对象保持完全相同的顺序?
【问题讨论】:
JSON 是零个或多个名称/值对的无序集合。 为什么需要订单?因为它不应该很重要? 我将这些 json 对象发送到服务器,对他们来说,键的顺序对于反序列化很重要,我知道这不符合 JSON 协议,但它就是这样,我们无法更改它 @Claudiu 为什么它很重要?他们是否尝试使用索引访问 JSON 值?您使用键来访问 JSON 中的值而不是索引。 @KeshuR。据我了解,他们正在使用一些基于树的解码,每个键都是一个节点,如果他们在另一个节点之前解码一个节点,则会引发错误 【参考方案1】:for (key, value) in OrderedDictionary
将维持秩序。
struct OrderedDictionary<KeyType:Hashable, ValueType>
private var _dictionary:Dictionary<KeyType, ValueType>
private var _keys:Array<KeyType>
init()
_dictionary = [:]
_keys = []
init(minimumCapacity:Int)
_dictionary = Dictionary<KeyType, ValueType>(minimumCapacity:minimumCapacity)
_keys = Array<KeyType>()
init(_ dictionary:Dictionary<KeyType, ValueType>)
_dictionary = dictionary
_keys = map(dictionary.keys) $0
subscript(key:KeyType) -> ValueType?
get
return _dictionary[key]
set
if newValue == nil
self.removeValueForKey(key)
else
self.updateValue(newValue!, forKey: key)
mutating func updateValue(value:ValueType, forKey key:KeyType) -> ValueType?
let oldValue = _dictionary.updateValue(value, forKey: key)
if oldValue == nil
_keys.append(key)
return oldValue
mutating func removeValueForKey(key:KeyType)
_keys = _keys.filter $0 != key
_dictionary.removeValueForKey(key)
mutating func removeAll(keepCapacity:Int)
_keys = []
_dictionary = Dictionary<KeyType,ValueType>(minimumCapacity: keepCapacity)
var count: Int get return _dictionary.count
// keys isn't lazy evaluated because it's just an array anyway
var keys:[KeyType] get return _keys
// values is lazy evaluated because of the dictionary lookup and creating a new array
var values:GeneratorOf<ValueType>
get
var index = 0
return GeneratorOf<ValueType>
if index >= self._keys.count
return nil
else
let key = self._keys[index]
index++
return self._dictionary[key]
extension OrderedDictionary : SequenceType
func generate() -> GeneratorOf<(KeyType, ValueType)>
var index = 0
return GeneratorOf<(KeyType, ValueType)>
if index >= self._keys.count
return nil
else
let key = self._keys[index]
index++
return (key, self._dictionary[key]!)
func ==<Key: Equatable, Value: Equatable>(lhs: OrderedDictionary<Key, Value>, rhs: OrderedDictionary<Key, Value>) -> Bool
return lhs._keys == rhs._keys && lhs._dictionary == rhs._dictionary
func !=<Key: Equatable, Value: Equatable>(lhs: OrderedDictionary<Key, Value>, rhs: OrderedDictionary<Key, Value>) -> Bool
return lhs._keys != rhs._keys || lhs._dictionary != rhs._dictionary
【讨论】:
SwiftyJSON 是否保证保单? 嘿,我已经更新了答案。我把你的问题弄错了。您可以使用上述类进行有序插入。事实上 SwiftufyJson 不保证订单。 我不太明白我应该如何将这个应用到我的案例中,您愿意详细解释一下吗以上是关于是否有一个 swift 库可以让您自定义 JSON 中键的顺序?的主要内容,如果未能解决你的问题,请参考以下文章