是否有一个 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 中键的顺序?的主要内容,如果未能解决你的问题,请参考以下文章

Swift 4 JSON 解析指南

Android 手把手教您自定义ViewGroup

Android 手把手教您自定义ViewGroup

文本记录软件—Note-C for Mac

php [WooCommerce Drip]此过滤器允许您自定义发送到Drip的订户自定义字段。这是发送第一个的示例

与 Xcode 一样,Android 中的按下按钮背景更改