插入顺序字典(如Java的LinkedHashMap)在Swift? [英] Insertion-Order Dictionary (like Java's LinkedHashMap) in Swift?

查看:991
本文介绍了插入顺序字典(如Java的LinkedHashMap)在Swift?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一个标准的swift类,或者是一个很好的开源类,它是一个Dictionary,但是把键插入顺序如 Java的LinkedHashMap

解决方案

Didn不知道一个,这是一个有趣的问题要解决(已经把它放在我的标准库中)大多数情况下,这只是一个维护一个字典和一个并排数组的问题。但是,对于od.keys中的键值()中的 c>和中的($,$,$)的标准操作,将以插入顺序进行迭代而不是半随机的方式。

  // 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& ValueType>){
_dictionary = dictionary
_keys = map(dictionary.keys){$ 0}
}

下标(key:KeyType) - >值类型? {
get {
return _dictionary [key]
}
set {
if newValue == nil {
self.removeValueForKey(key)
}
else {
self.updateValue(newValue !, forKey:key)
}
}
}

mutating func updateValue( value:ValueType,forKey键:KeyType) - >值类型? {
let oldValue = _dictionary.updateValue(value,forKey:key)
如果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}}

//键不是懒惰的评估,因为它只是一个数组反正
var keys:[KeyType ] {get {return _keys}}

//值由于字典查找和创建新数组而被延迟
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:Equable>(lhs:OrderedDictionary< Key,Value>,rhs:OrderedDictionary< Key,Value>) - > Bool {
return lhs._keys == rhs._keys&& lhs._dictionary == rhs._dictionary
}

func!=< Key:Equatable,Value:Equable>(lhs:OrderedDictionary< Key,Value>,rhs:OrderedDictionary&值>) - > Bool {
return lhs._keys!= rhs._keys || lhs._dictionary!= rhs._dictionary
}


Is there a standard swift class, or a good open-source class that is a Dictionary, but keeps keys in insertion-order like Java's LinkedHashMap?

解决方案

Didn't know of one and it was an interesting problem to solve (already put it in my standard library of stuff) Mostly it's just a matter of maintaining a dictionary and an array of the keys side-by-side. But standard operations like for (key, value) in od and for key in od.keys will iterate in insertion order rather than a semi random fashion.

// OrderedDictionary behaves like a Dictionary except that it maintains
//  the insertion order of the keys, so iteration order matches insertion
//  order.
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
}

这篇关于插入顺序字典(如Java的LinkedHashMap)在Swift?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆