Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell if a variable is an array

Tags:

arrays

swift

I have a Swift function that accepts Any and I want it to be able to accept an array of Strings, an array of Ints, a mixed array, or an array of arrays, etc. It also can accept just a String or an Int, etc, not in an array.

So I have this:

    private func parse(parameter: Any) {
        if parameter is Int {
            // Int
        } else if (parameter is Float) || (parameter is Double) {
            // Double
        } else if parameter is String {
            // String
        } else if parameter is Bool {
            // Bool
        } else if let array = parameter as? [Any] {
            // Should catch all Arrays
        } else {
            assert(false, "Unsupported type") // [String] ends up here
        }
    }

But if I call parse(["Strings"]), the assert is raised. How can I catch all types of Arrays?

edit - there was some confusion as to what I'm trying to accomplish. I basically need to return a String based on the type, so Int -> "" and String -> "", so an array would make recursive calls to return "..."

This post is marked as a duplicate, but that other question is about Javascript, not Swift.

like image 790
Ryan Avatar asked Oct 07 '14 00:10

Ryan


People also ask

How do I check if a variable is an array?

isArray(variableName) method to check if a variable is an array. The Array. isArray(variableName) returns true if the variableName is an array. Otherwise, it returns false .

What variable is an array?

The array variable is a type of variable which enables you to store multiple values of the same type. UiPath Studio supports as many types of arrays as it does types of variables. This means that you can create an array of numbers, one of strings, one of boolean values and so on.

How do you check if a variable is an array in Java?

The isArray() method of Class is used to check whether an object is an array or not. The method returns true if the given object is an array. Otherwise, it returns false .

How do you check if an object is an array of values?

Checking if Array of Objects Includes Object We can use the some() method to search by object's contents. The some() method takes one argument accepts a callback, which is executed once for each value in the array until it finds an element which meets the condition set by the callback function, and returns true .


1 Answers

The key to understanding typing and type related issues in Swift is that all roads lead to protocols.

The challenge of this problem is detecting any type of array, not just one concrete type. The OP's example failed because [Any] is not a base class or a generalized pattern of [String], that is to say, that (from what I can tell), in Swift [T] is not covariant on T. Beyond that, you cannot check for SequenceType or CollectionType since they have associated types (Generator.Element).

The idiomatic solution is thus to use a marker protocol to indicate which types you want to match your criteria. As illustrated below, you achieve this by creating an empty protocol, and associating it with the types of interest.

import Foundation


protocol NestedType {}
extension Array: NestedType {}
extension Set: NestedType {}
extension Dictionary: NestedType {}
extension NSSet: NestedType {}

protocol AnyTypeOfArray {}
extension Array: AnyTypeOfArray {}
extension NSArray: AnyTypeOfArray {}

protocol AnyTypeOfDictionary {}
extension Dictionary: AnyTypeOfDictionary {}


func printType(v:Any) {
    if v is NestedType {
        print("Detected a nested type")
    }

    if v is AnyTypeOfArray {
        print("\t which is an array")
    }

    else if v is AnyTypeOfDictionary {
        print("\t which is a dictionary")
    }
}


printType([String:Int]())
printType([Int]())
printType(NSArray())

The output of which is:

Detected a nested type
     which is a dictionary
Detected a nested type
     which is an array
Detected a nested type
     which is an array
like image 51
Chris Conover Avatar answered Oct 11 '22 13:10

Chris Conover