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?]'
あなたの問題は、map
がArray
に適用された場合でも、常にDictionary
を返すという事実にあります。エラーメッセージは基本的に、Dicitonary
を返すようにメソッドを宣言したが、内部のステートメントはArray
([T]
-someタイプTのオブジェクトを持つ配列を意味します。あなたの場合、map
によって返される配列にはtuplesが含まれます(詳細については here )。この場合、キーと値のペアのように見えますが、ディクショナリ内のキーと値のペアとは異なります。基本的に、タプルを使用すると、メソッドから複数の値/オブジェクトを返すことができます。それらはanonymous構造と考えることができます。
私の意見では、必要なことを達成するためにmap
を使用する必要はありません。Xcoder氏が提供するソリューションはその方法です。
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
を適用する準備ができました。 2つのパラメーターを関数に渡します。 1つ目は、「アキュムレータ」で、最終的な結果を構築し続けます。この場合は、別の辞書です。 2番目は、元のディクショナリの要素であり、key
およびvalue
と呼ばれるキーと値のペアのTupleとして表されます。
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}]
私はそのエラーを修正する方法を理解できませんでした。また、拡張機能または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
、 どちらが正しい。
辞書をマッピングしないのはなぜですか?AsLosiowaty彼の優れた答えで指摘したように、map
は常にArray
を返します。この場合、Array
は Tuples ([T]
)。私の考えでは、このコンテキストではマップ関数は必要ありません。さらに、実行するにはさらに多くのコードが必要です。
お役に立てれば!