69429


Swiftで以下のようなJSON文字列を作成したいと考えています。

[code]

    {"testDict": {"aaa": 0.0, "bbb": 0.0, "ccc": 0.0}}
    
[/code]

試しに以下のように書いてみたのですが、エラーが出ます。

[code]

    var testJsonMap = Dictionary<String,Any>()
    testJsonMap["testDict"] = Dictionary<String,Any>()
    
    for testObj in ["aaa","bbb","ccc"]
    {
        testJsonMap["testDict"][testObj] = 0.0
    }
    
[/code]

エラー内容は以下のようなものです。

[code]

    Value of type 'Any?' has no subscripts
    
[/code]

どうしたら辞書内辞書を生成することができますでしょうか？


CC BY-SA 4.0
2020-08-10T14:20:36.130
69428
2020-08-10T15:09:59.200
36446
question
swift
Swiftで辞書内辞書を作る方法


こういうときは、型を自分で書かないで型推論させるとやりやすいと考えます。

[code]

    var value = [
        "testDict": [
            "aaa": 0.0,
            "bbb": 0.0,
            "ccc": 0.0
        ]
    ]
    print(value)
    
[/code]

上記コードをXcodeで書き、`value`にXcodeでマウスカーソルを当て、オプションキーを押しながらクリックすると型推論した結果の型を教えてくれます。

[![画像の説明をここに入力](https://i.stack.imgur.com/nNfv4.png)](https://i.stack.imgur.com/nNfv4.png)

ということで、あなたが作りたい型が`[String: [String: Double]]`だとわかりますので、

[code]

    var testJsonMap = [String: [String: Double]]()
    testJsonMap["testDict"] = [String: Double]()
    
    for testObj in ["aaa","bbb","ccc"]
    {
        testJsonMap["testDict"]?[testObj] = 0.0
    }
    
    print(testJsonMap)
    
[/code]

で完成です。

コメントを受けての追記:

> ありがとうございます。仮に、{"testDict": {"aaa": 0.0, "bbb": 0.0, "ccc": 0.0},
> "testName":"Taro", "testAge":20}などのように、あとから要素が増やしていく場合、var testJsonMap =
> String: [String: Double]は必ず最初の定義を変えていかないといけないのでしょうか？
[code]

    var value = ["testDict": ["aaa": 0.0, "bbb": 0.0, "ccc": 0.0], "testName":"Taro", "testAge":20] as [String : Any]
    print(value)
    
    value["AA"] = ["BB":"CC"]
    print(value)
    
[/code]

なんてこともできました。（これはJavaScriptでなく、SwiftなのでAnyは基本的に使いたくないのが、私の個人的な感想です）。

はじめに空の辞書を作る場合は下記のように書けました。

[code]

    var value = [String : Any]()
    print(value)
    
    value["AA"] = ["BB":"CC"]
    value["num"] = 10.0
    print(value)
    
[/code]

さらにコメントを受けての追記:

> value = ["testDict": ["aaa": 0.0, "bbb": 0.0, "ccc": 0.0]]に対して["testDict":
> ["aaa": 0.0, "bbb": 0.0, "ccc":
> 0.0,"ddd":0.1]]のように追加していく方法はありますか？value["testDict"] =
> ["ddd":0.1]としてしまうと上書きされてしまうので上書きせずに追加したいです。

確かに直接やろうとすると、`Value of type 'Any?' has no subscripts`というエラーが出てしまいますね。

Anyでは型情報がなくなってしまうため、下記のようにすればできます。  
（果たしてここまでしてAnyが使いたいかは微妙なところだと私は考えますが）

[code]

    var value = ["testDict": ["aaa": 0.0, "bbb": 0.0, "ccc": 0.0], "testName":"Taro", "testAge":20] as [String : Any]
    print(value)
    
    if var testDict = value["testDict"] as? [String: Any]{
        testDict["ddd"] = 0.1
        value["testDict"] = testDict
    }
    
    print(value)
    
[/code]


CC BY-SA 4.0
2020-08-10T14:25:00.087
69429
2020-08-10T15:09:59.200
2020-08-10T15:09:59.200
9008
9008
69428
answer