Доступ к значениям словаря в массиве в Swift

У меня есть массив с данными для моих разделов TableView

let menuItems : Dictionary<String,Dictionary<String,String>>[] = [
    [
        "data" : [
            "name":"test",
            "image":"test.png"
        ]
    ],
    [
        "data" : [
            "name":"test2",
            "image":"test2.png"
        ]
    ]
]

Я пытаюсь получить к нему доступ с помощью индекса

func tableView(tableView: UITableView!, titleForHeaderInSection section: Int) -> String! {
    return menuItems[section]["data"]["name"]
}

и есть ошибка

Could not find member 'subscript'

Я прочитал много похожих вопросов о stackru, но до сих пор не понял, как это исправить. Я пытался развернуть с "!" символ и использовал другие переменные - нет результата.

Не могли бы вы объяснить, как это работает, пожалуйста?

1 ответ

Решение
println(menuItems[0]["data"]!["name"])

Краткий ответ: menuItems[0]["data"] возвращает необязательный словарь.

Вы можете посмотреть на вывод ниже REPL, чтобы понять проблему.

  1. устанавливает объект.
  2. показывает, что массив возвращает обычный словарь. Если индекс выходит за пределы диапазона, вместо возврата необязательного словаря будет выдана ошибка.
  3. показывает, что доступ к ключу в словаре, который не существует, вернет ноль
  4. показывает, что доступ к ключу в словаре вернет необязательный тип его значения. Например, если словарь хранит строки в своих значениях, он вернет строку? когда индексируется в.
  5. показывает, что мы не можем использовать подписки на дополнительный словарь.
  6. показывает, что мы можем заставить дополнительный словарь быть словарем, потому что мы знаем, что это не ноль. REPL показывает нам, что новый тип возврата Dictionary<String, String>
  7. показывает, что мы можем затем использовать индексы для получения самых внутренних значений, и это возвращает нам необязательную строку. Необязательные строки можно распечатать, так что мой код выше не нужно ни секунды !,
  8. показывает, что если мы принудительно возвращаем оба возвращаемых типа словаря к их необязательным типам, мы возвращаем обычное значение (строку).

В реальном коде вы, вероятно, захотите проверить наличие опций и соответственно обработать nils.

1> позвольте меню: Dictionary<String, Dictionary<String, String>>[] = [["dict1": ["key": "val"]], ["dict2": ["key": "val"]]]

menu: Dictionary<String, Dictionary<String, String>>[] = size=2 {
  [0] = {
    [0] = {
      key = "dict1"
      value = {
        [0] = {
          key = "key"
          value = "val"
        }
      }
    }
  }
  [1] = {
    [0] = {
      key = "dict2"
      value = {
        [0] = {
          key = "key"
          value = "val"
        }
      }
    }
  }
}

2> меню [0]

$R1: Dictionary<String, Dictionary<String, String>> = {
  [0] = {
    key = "dict1"
    value = {
      [0] = {
        key = "key"
        value = "val"
      }
    }
  }
}

3> меню [0] ["ключ"]

$R2: Dictionary<String, String>? = nil

4> меню [0] ["dict1"]

$R3: Dictionary<String, String>? = Some {
  [0] = {
    key = "key"
    value = "val"
  }
}

5> menu [0] ["dict1"] ["key"]

REPL:6:1: error: could not find member 'subscript'
menu[0]["dict1"]["key"]
^~~~~~~~~~~~~~~~~~~~~~~

6> menu [0] ["dict1"]!

$R4: Dictionary<String, String> = {
  [0] = {
    key = "key"
    value = "val"
  }
}

7> menu [0] ["dict1"]! ["Key"]

$R5: String? = "val"

8> menu [0] ["dict1"]! ["Key"]!

$R6: String = "val"
Другие вопросы по тегам