class MutableOrderedDictionary: NSDictionary {

    let _values: NSMutableArray = []

    let _keys: NSMutableOrderedSet = []

    override var count: Int {

        return _keys.count

    }

    override func keyEnumerator() -> NSEnumerator {

        return _keys.objectEnumerator()

    }

    override func object(forKey aKey: Any) -> Any? {

        let index = _keys.index(of: aKey)

        if index != NSNotFound {

            return _values[index]

        }

        return nil

    }

    func setObject(_ anObject: Any, forKey aKey: String) {

        let index = _keys.index(of: aKey)

        if index != NSNotFound {

            _values[index] = anObject

        } else {

            _keys.add(aKey)

            _values.add(anObject)

        }

    }

}

extension MutableOrderedDictionary {

    private static let defaultOrder: ((String, Any), (String, Any)) -> Bool = {

        $0.0.compare($1.0, options: [.forcedOrdering, .caseInsensitive]) == .orderedAscending

    }

    static func sorted(object: Any, by areInIncreasingOrder: ((key: String, value: Value), (key: String, value: Value)) -> Bool = defaultOrder) -> Any {

        if let dict = object as? [String: Any] {

            return MutableOrderedDictionary(dict, by: areInIncreasingOrder)

        } else if let array = object as? [Any] {

            return array.map { sorted(object: $0, by: areInIncreasingOrder) }

        } else {

            return object

        }

    }

    convenience init(_ dict: [String: Any], by areInIncreasingOrder: ((key: String, value: Value), (key: String, value: Value)) -> Bool = defaultOrder) {

        self.init()

        dict.sorted(by: areInIncreasingOrder)

            .forEach { setObject(MutableOrderedDictionary.sorted(object: $0.value, by: areInIncreasingOrder), forKey: $0.key) }

    }

}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐