I'm writing an extension to bridge the dictionary values between FirebaseDatabase and 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)
})
}
}
But I get thrown this error when I try to build:
map produces '[T]', not the expected contextual result type '[String: Any?]'
Your problem lies with the fact, that map
always returns an Array
, even when applied on a Dictionary
. Your error message basically means, that you declared your method as returning a Dicitonary
, but the statement inside returns an Array
([T]
- means an Array with objects of some type T). In your case, the array returned by map
will contain tuples (more about them here). In this case it looks like a key value pair, but its not equivalent to a key-value pair inside a Dictionary. Basically, tuples enable you to return more than one value/object from method. You can think of them as of anonymous structures.
In my opinion, there is no need to use a map
to accomplish what you need - the solution provided by Mr. Xcoder is the way to go.
If you really want to use something functional like map
, the method you actually want is reduce
.
I'll demonstrate. To make things as clear as possible, I think it will help if we separate out the transformation to which your values are being subjected into a function of its own:
func dateToSeconds(_ thing:Any?) -> Any? {
guard let date = thing as? Date else {return thing}
return date.timeIntervalSince1970
}
Okay, so here's our test dictionary:
let d1 : [String:Any?] = ["1":Date(), "2":"two", "3":15, "4":true]
Now we're ready to apply reduce
. It passes two parameters into its function. The first is the "accumulator" where we keep building up the ultimate result, which in this case is another dictionary. The second is an element of the original dictionary, represented as a tuple of key-value pairs called key
and value
:
let d2 = d1.reduce([String:Any?]()) { (dict, tuple) in
var dict = dict
dict[tuple.key] = dateToSeconds(tuple.value)
return dict
}
And when we examine d2
, we see that we have got the right answer:
d2 // ["3": {some 15}, "2": {some "two"}, "1": {some 1486228695.557882}, "4": {some true}]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With