14

我正在编写一个扩展来桥接 FirebaseDatabase 和Eureka之间的字典值。

private extension Dictionary {
    func firebaseFriendlyDictionary() -> [String: Any?] {
        return self.map({ (key: String, value: Any?) -> (String, Any?) in
            if value is NSDate {
                return (key, (value as! NSDate).timeIntervalSince1970)
            }
            return (key, value)
        })
    }
}

但是当我尝试构建时,我得到了这个错误:

map produces '[T]', not the expected contextual result type '[String: Any?]'

4

3 回答 3

7

您的问题在于,即使应用于 a ,它也map总是返回a 。您的错误消息基本上意味着您将方法声明为返回 a ,但里面的语句返回一个( - 表示带有某种类型 T的对象的数组)。在您的情况下,返回的数组将包含元组(更多关于它们的信息)。在这种情况下,它看起来像一个键值对,但它不等同于字典中的键值对。基本上,元组使您能够从方法中返回多个值/对象。您可以将它们视为匿名结构。ArrayDictionaryDicitonaryArray[T]map

在我看来,没有必要使用 amap来完成您所需要的 - Xcoder 先生提供的解决方案是要走的路。

于 2017-02-04T16:51:38.670 回答
6

如果你真的想使用类似函数的东西map,你真正想要的方法是reduce.

我会示范。为了使事情尽可能清楚,我认为如果我们将你的价值观所经历的转变分离成它自己的功能会有所帮助:

func dateToSeconds(_ thing:Any?) -> Any? {
    guard let date = thing as? Date else {return thing}
    return date.timeIntervalSince1970
}

好的,这是我们的测试词典:

let d1 : [String:Any?] = ["1":Date(), "2":"two", "3":15, "4":true]

现在我们准备申请了reduce。它将两个参数传递给它的函数。第一个是我们不断建立最终结果的“累加器”,在这种情况下是另一个字典。第二个是原始字典的元素,表示为键值对的元组key,称为and value

let d2 = d1.reduce([String:Any?]()) { (dict, tuple) in
    var dict = dict
    dict[tuple.key] = dateToSeconds(tuple.value)
    return dict
}

当我们检查 时d2,我们发现我们得到了正确的答案:

d2 // ["3": {some 15}, "2": {some "two"}, "1": {some 1486228695.557882}, "4": {some true}]
于 2017-02-04T17:26:35.640 回答
3

我无法弄清楚如何修复该错误,也无法使用扩展名或 a 成功实现所需的结果map(),但我有一个替代解决方案,使用函数

声明字典:

var date = NSDate()
var swiftDict:[String : Any?] = ["1":  date, "2": "two", "3": 15, "4": true]

功能:

func firebaseFriendlyDictionary(_ dict: [String : Any?]) -> [String : Any?]{
    var Dict = dict
    for (key, value) in dict
    {
        if (value is NSDate){
            Dict[key] = (value as! NSDate).timeIntervalSince1970
        }
    }
    return Dict
}

用法:

swiftDict = firebaseFriendlyDictionary(swiftDict)

测试:

假设我们有2017-02-04 16:42:46 +0000输出的日期是1486226566.2349629,这是正确的。

为什么不映射字典? 正如Losiowaty在他出色的答案中指出的那样,map总是返回一个Array,在这种情况下是Array([T]) 的一个。在我看来,在这种情况下不需要地图功能,而且它需要更多的代码来完成。

希望这可以帮助!

于 2017-02-04T16:49:10.587 回答