How do I check if an object is a collection? (Swift)
Collection
can no longer be used for type-checking, hence Ahmad F's solution would no longer compile.
I did some investigation. Some people advice to bridge to obj-c collections and use isKindOfClass
, others try to employ reflection (by using Mirror
). Neither is satisfactory.
There's a pretty straight-forward, a bit rough yet efficient way to accomplish the task via splitting object type if our concern is Array
, Dictionary
or Set
(list can be updated):
func isCollection<T>(_ object: T) -> Bool {
let collectionsTypes = ["Set", "Array", "Dictionary"]
let typeString = String(describing: type(of: object))
for type in collectionsTypes {
if typeString.contains(type) { return true }
}
return false
}
Usage:
var set : Set! = Set<String>()
var dictionary : [String:String]! = ["key" : "value"]
var array = ["a", "b"]
var int = 3
isCollection(int) // false
isCollection(set) // true
isCollection(array) // true
isCollection(dictionary) // true
Hard-code is the drawback but it does the job.
NOTE: This solution does NOT work with Swift 5+.
func isCollection<T>(object: T) -> Bool {
switch object {
case _ as Collection:
return true
default:
return false
}
}
Calling:
// COLLECTION TESTING //
let arrayOfInts = [1, 2, 3, 4, 5]
isCollection(object: arrayOfInts) // true
let setOfStrings:Set<String> = ["a", "b", "c"]
isCollection(object: setOfStrings) // true
// [String : String]
let dictionaryOfStrings = ["1": "one", "2": "two", "3": "three"]
isCollection(object: dictionaryOfStrings) // true
// NON-COLLECTION TESTING //
let int = 101
isCollection(object: int) // false
let string = "string" // false
let date = Date()
isCollection(object: date) // false