Доступ к индексам массива любого типа со ссылкой на словари - PullRequest
0 голосов
/ 17 октября 2018

В SO много вопросов по поводу использования нижнего индекса в массиве объектов типа ЛЮБОЙ, которые обычно рекомендуют приводить любой объект к типу переменной, который может принимать нижний индекс с чем-то вроде

if let addresses = profile["Addresses"] as? [[String: Any]] 
* 1003.* В моем случае Array - это массив словарей формы (paramName: value) или (NSString: Float), однако, несмотря на все ответы на SO, я не могу понять синтаксис, чтобы сообщить компилятору, что AnyОбъект - это словарь.

Мой оригинальный код генерирует ошибку:

func getStringFromSortedArray (sortedArray:Array<Any>) -> String{

for i in 0 ..< sortedArray.count {
  if let paramName = sortedArray[i]["param"]  {
               //run some code
}

Я пытался

for i in 0 ..< sortedArray.count {
  if let paramName = sortedArray[i]["param"] as? [[String: Any]]  {
               //run some code
}

,

if let sortedArray = sortedArray as? [[Dictionary: Any]] {                
for i in 0 ..< sortedArray.count {
  if let paramName = sortedArray[i]["param"]  {
               //run some code
}
}

имножество изменений без успеха.

Может ли кто-нибудь указать мне на исправление синтаксиса, чтобы сообщить компилятору, что объект Any является словарем?Если кто-то думает, что на этот вопрос уже был дан ответ, я был бы признателен, если бы вы указали мне пример с набором словарей, так как я уже рассматривал ответы с различными настройками.

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

Давайте просто посмотрим на проблему с вашей первой строкой кода:

  func getStringFromSortedArray (sortedArray:Array<Any>) -> String {

Это неправильно, потому что вы не говорите, какой тип элементов массива.Вы знаете , что это массив словарей, но вы скрываете этот факт от компилятора.Это означает, что вы не можете никуда идти отсюда.

Так что, если вы знаете, что это массив словарей, вы должны сказать , это массив словарей:

  func getStringFromSortedArray (sortedArray:[[AnyHashable:Any]]) -> String {

Теперь, если вы знаете больше, вы должны сказать больше.Например, если вы знаете, что все ключи в этих словарях являются строками, вам следует сказать следующее:

  func getStringFromSortedArray (sortedArray:[[String:Any]]) -> String {

Если вы знаете, что значения ввсе словари одного типа, вы также должны сказать, что:

  func getStringFromSortedArray (sortedArray:[[String:Float]]) -> String {

Всегда будьте настолько конкретны, насколько это возможно, когда вы объявляете тип чего-либо.

0 голосов
/ 17 октября 2018

Если я правильно понимаю, вы говорите, что sortedArray - это массив словарей типа [[String : Any]]полагаю Вы также говорите, что ключ "param" содержит строку, и именно это вы пытаетесь использовать в этой функции.Если это правильно, то кажется, что вы были очень близки, но упустили несколько вещей:

func getStringFromSortedArray (sortedArray:Array<Any>) -> String {
  //If your sortedArray is an array of dictionaries let's cast it as such
  guard let dictionaries = sortedArray as? [[String : Any]] else { return "None Found" }
  for i in 0 ..< dictionaries.count {
    //Now we can loop through the dictionaries, and check that "param" contains a string
    if let paramName = dictionaries[i]["param"] as? String {
      //Now we have a reference to "paramName" and can return it or do whatever "run some code" means
           //run some code
  }
}

Конечно, вам нужно будет настроить то, что произойдет, если оператор guard не удастся, и вы также получитедобавить правильное возвращаемое значение, если цикл for завершается без поиска искомого значения.

...