Dan Beaulieu
Dan Beaulieu

Reputation: 19964

Looping through a dictionary and checking each value type

How do I loop through a dictionary and check for each items value type?

Example dictionary:

var dict = ([
    "a number" : 1,
    "a boolean" : false,
    "a string" : "Hello"
])

My attempts at checking for values:

for item in dict.1 {
    if let current = item as? NSNumber {
        print(current)
    }
}

and I tried this:

for item in settings {
    if item[1] == item[1] as NSNumber {
        print(item)
    }
}

Important note:

As @Leo pointed out, it's important to keep track of what your dictionary's value type is while comparing. The dictionary that I included as my example would be of type [String : NSObject] and the dictionary in my project was of type [String : NSNumber]. They have to be approached differently!

Upvotes: 2

Views: 3978

Answers (4)

nPn
nPn

Reputation: 16758

You can also use dynamicType to find the class, then use a simple switch statement to take the appropriate action(s)

var dict = ([
  "a number" : 1,
  "a boolean" : false,
  "astring" : "Hello"
  ])

for (k,v) in dict {
  switch "\(v.dynamicType)" {
    case "__NSCFString":
      println("found String = \(v)")
    case "__NSCFBoolean":
      println("found Boolean = \(v as! Bool)")
    case "__NSCFNumber":
      println("found Number = \(v)")
    default:break
  }
}

Upvotes: 1

Leo
Leo

Reputation: 24714

You can use is in swift

var dict = ([
    "a number" : 1,
    "a boolean" : false,
    "a string" : "Hello"
])

for (key,value) in dict{
    if value is String{
        println(value)
    }
}

Also you can get className

for (key,value) in dict{
   println(String.fromCString(object_getClassName(value)))

}

This will log

Optional("__NSCFString")
Optional("__NSCFNumber")
Optional("__NSCFBoolean")

Update:

Swift is a type safe language,so if you have a dictionary like this

var dict = ([
        "a number" : 1,
        "a boolean" : false,
        ])

The dict is type of [String : NSNumber],so you do not need to check.

But,if you have a dictionary like this

 var dict = ([
        "a number" : 1,
        "a boolean" : false,
        "a string" : "Hello"
        ])

Then dict is type of [String:NSObject],in this case you need to check type.

Update,check if it is Int or Bool

Better to declare your dictionary to [String:Any] Then

      var dict:[String:Any] = ([
        "a number" : 1,
        "a boolean" : false,
        ])

    for (key,value) in dict{
        if value is Bool{
            println(value)
       }
        if value is Int{
            println(value)
        }
    }

Upvotes: 5

Dan Beaulieu
Dan Beaulieu

Reputation: 19964

For those who are having issues with warnings, make sure you check your type as @Leo stated above. If your value type is of NSNumber, you'll get errors. If it's of type NSObject use @Leo's or @nPn's answers.

enter image description here

This is working for me in my project which has a value type of NSNumber:

for (key, value) in settings {

    if value == value as Bool {
        print(value)
    }
    if value == value as NSNumber {
        print(value)
    }
}

Upvotes: 0

nPn
nPn

Reputation: 16758

From the swift reference, here is how to iterate over a dictionary

Iterating Over a Dictionary

You can iterate over the key-value pairs in a dictionary with a for-in loop. Each item in the dictionary is returned as a (key, value) tuple, and you can decompose the tuple’s members into temporary constants or variables as part of the iteration:

for (airportCode, airportName) in airports {
        println("\(airportCode): \(airportName)")
    }
    // YYZ: Toronto Pearson
    // LHR: London Heathrow

So this should work for your example.

var dict = ([
  "a number" : 1,
  "a boolean" : false,
  "a string" : "Hello"
  ])


for (k,v) in dict {
  if let x = v as? NSNumber {
    println("x = \(x)")
  }
}

Upvotes: 1

Related Questions