【问题标题】:Dictionary extension to convert nil values to NSNull将 nil 值转换为 NSNull 的字典扩展
【发布时间】:2015-12-02 08:52:06
【问题描述】:

由于您不能将Dictionary<String, AnyObject?> 直接转换为NSDictionary,我想编写一个Dictionary 扩展来进行这种转换(用NSNull 代替任何nils)。

但为了做到这一点,我的Dictionary 扩展必须限制为值为Optional<T> where T:AnyObject 的字典。我该如何为此编写类型约束?

【问题讨论】:

    标签: swift generics nsdictionary


    【解决方案1】:

    您不能在字典中添加 nil。因此,您必须将其强制转换为someType?,这样您才能拥有密钥。

    借用 Q/A 的 OptionalConvertible 解决方案:

    protocol OptionalConvertible {
        typealias WrappedValueType = AnyObject
        func toOptional() -> WrappedValueType?
    }
    
    extension Optional: OptionalConvertible {
        typealias WrappedValueType = Wrapped
    
        // just to cast `Optional<Wrapped>` to `Wrapped?`
        func toOptional() -> WrappedValueType? {
            return self
        }
    }
    

    extension Dictionary where Value: OptionalConvertible, Key: NSCopying {
        //dict: Dictionary<Key, Optional<Value>>
        func convertToNSDictionary() -> NSDictionary {
    
            let mutableDict : NSMutableDictionary = NSMutableDictionary()
    
            for key in self.keys {
                if let maybeValue = self[key] {
                    if let value = maybeValue.toOptional() {
                        mutableDict[key] = value as? AnyObject
                    } else {
                        mutableDict[key] = NSNull()
                    }
                }
            }
            return mutableDict
    
        }
    }
    

    var optionalObject : UIView? = nil
    
    var dict : [NSString:AnyObject?] = [:]
    dict["alpha"] = 1
    dict["beta"] = 2
    dict["delta"] = optionalObject as AnyObject? // force a nil into the dict
    
    dict // ["beta": {Some 2}, "alpha": {Some 1}, "delta": nil]
    
    let nsdict = dict.convertToNSDictionary() // ["alpha": 1, "beta": 2, "delta": {NSObject}]
    

    或者更实用的方法:

    extension NSDictionary {
    
        static func fromDictionary<Key: Hashable, Value:AnyObject where Key: NSCopying>(dictionary:Dictionary<Key, Value>) -> NSDictionary {
    
            let mutableDict : NSMutableDictionary = NSMutableDictionary()
    
            for key in dictionary.keys {
                if let value = dictionary[key] {
                    mutableDict[key] = value
                } else {
                    mutableDict[key] = NSNull()
                }
            }
            return mutableDict
        }
    
        static func fromDictionary<Key: Hashable, Value:AnyObject where Key: NSCopying>(dict: Dictionary<Key, Optional<Value>>) -> NSDictionary {
    
            let mutableDict : NSMutableDictionary = NSMutableDictionary()
    
            for key in dict.keys {
                if let maybeValue = dict[key] {
                    if let value = maybeValue {
                        mutableDict[key] = value
                    } else {
                        mutableDict[key] = NSNull()
                    }
                }
            }
            return mutableDict
        }
    }
    

    【讨论】:

    • 谢谢,但是这不是字典的扩展;您的函数也可能是全局函数。成员函数将是实现这一点的更好方法,因此我提出了关于类型约束的问题。
    • @phu 这个函数正是你想要的。它应该适用于哪些更广泛的限制?
    • 我没有要求你自己写函数;请重新阅读我原来的问题。我问的是类型约束。例如,extension Dictionary where Value:AnyObject 将定义一个扩展,该扩展仅适用于其值实现 AnyObject 的字典。我想知道如何创建一个适用于其值为T? where T:AnyObject 的字典的扩展。
    • @phu 选项和泛型/约束不能很好地混合。他们可能有朝一日。更新了答案更具体的约束。
    • @phu 不要对约束视而不见。就像泛型一样,它们往往使事情复杂化而不是简化。获得正确的结果更为重要。
    猜你喜欢
    • 1970-01-01
    • 2014-10-23
    • 2016-07-01
    • 2015-06-06
    • 2017-10-30
    • 2018-02-08
    • 2016-06-06
    相关资源
    最近更新 更多