Swift 3:如何检查通用数组的类型

时间:2017-02-27 17:11:24

标签: swift

我声明了一个通用数组

  fileprivate var array: [T?]

我有一个方法average(),它将计算平均值,如果' T'是Int还是Float;否则返回0

  public   func average() -> Float {
    var mean = 0
    if T is Int or Float {
     for   index in (0..<array.count-1){
         mean = mean+array[index]
        }
        mean = mean/array.count
     }
     return mean;
  }

问题:如何检查数组是否保持Int / Float(如果T是Int或Float ,在上面的代码中)

5 个答案:

答案 0 :(得分:2)

这是一种协议工具。您的问题的有用协议是FloatingPoint来处理浮点类型(如Float)和Integer来处理有符号整数类型(如Int)。这些实现略有不同,因此最好分别编写每个实现。这样做将确保此方法仅适用于T的适当类型(而不是所有可能的类型,并且在这些情况下仅返回0)。

extension MyStruct where T: FloatingPoint {
    func average() -> T {
        let sum = array.flatMap{$0}.reduce(0, +)
        let count = T(array.count)
        return sum.divided(by: count)
    }
}

extension MyStruct where T: Integer {
    func average() -> Float {
        let sum = array.flatMap{$0}.reduce(0, +)
        let count = array.count
        return Float(sum.toIntMax()) / Float(count.toIntMax())
    }
}

编辑:关于下面的Caleb评论的更多内容,您可能会认为将整数转换为浮点数来生成它们的平均值是可以的。但是,如果不仔细考虑您的范围,这通常是不安全的。例如,考虑[Int.min, Int.max]的平均值。那是[-9223372036854775808, 9223372036854775807]。平均值应为-0.5,以及上面示例返回的内容。但是,如果您将所有内容转换为浮点数以进行求和,那么您将获得0,因为Float无法准确表达Int.max。我在实时代码中看到了这些人,当他们不记得非常大的花车x == x+1时。

Float(Int.max) == Float(Int.max - 1) // true

答案 1 :(得分:0)

您需要遍历数组并使用“if let”来解包数组中值的类型。如果他们是一个整体处理他们,如果他们是浮动处理他们另一种方式。

//在迭代数组时检查元素以查看它们是浮点数还是整数。

RewriteEngine On

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

答案 2 :(得分:0)

您可以通过以下方式使用Swift 3中引入的type方法:

let type = type(of: array)
print("type: \(type)") // if T is String, you will see Array<Optional<String>> here

答案 3 :(得分:0)

以下是高级别说明:

... inside a loop which allows indexing
if let ex = array[index] as? Int {
    your code
    continue // go around the loop again, you're all done here
}
if let ex = array[index] as? Float {
    // other code
    continue  // go around the loop again, you're all done here
}
// if you got here it isn't either of them
// code to handle that
... end of inside the loop

如果不够明确,我可以进一步解释。

答案 4 :(得分:0)

这可能是最简单的方法:

var average: Float {
    let total = array.reduce(0.0) { (runningTotal, item) -> Float in

        if let itemAsFloat = item as? Float {
            return runningTotal + itemAsFloat
        }
        else if let itemAsInt = item as? Int {
            return runningTotal + Float(itemAsInt)
        }
        else {
            return runningTotal
        }
    }
    return total / Float(array.count)
}

显然,如果你想要它可以是一个功能,并且取决于你想要如何使用它,你可能需要调整它。

*请注意,Int数组中可能同时包含FloatT。例如如果TAny