Search code examples
iosswifttypesany

Access subscript of array of type any refering to dictionaries


There are a lot of questions on SO about using a subscript on an Array of objects of type ANY that generally recommend casting the Any Object to a variable type that can take a subscript with something like

if let addresses = profile["Addresses"] as? [[String: Any]] 

In my case, the Array is an array of dictionaries of form (paramName:value) or (NSString: Float), however, despite all the answers on SO, I can't figure out the syntax to tell the compiler that the Any object is a dictionary.

My original code generates the error:

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

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

I have tried

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
}
}

and a whole lot of variations without success.

Can someone point me to correct syntax to inform compiler that the Any object is a dictionary? If someone thinks this question has been answered before, I would appreciate your point me to an example with an array of dictionaries as I have already looked at answers with different setups.


Solution

  • Let's just look at the problem with your first line of code:

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

    This is wrong because you are not saying what the type of the array elements is. You know it is an array of dictionaries, but you are hiding that fact from the compiler. This means you can't go anywhere from here.

    So if you know it is an array of dictionaries, you should say it is an array of dictionaries:

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

    Now, if you know more, you should say more. For example, if you know that all the keys in these dictionaries are strings, you should say so:

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

    If you know that the values in the dictionaries are all of the same type, you should say that too:

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

    Always be as specific as you can when you declare the type of something.