'Adding a double to all elements of a numeric array and return Array<Double>
I want to add NumPy like functionality to a Swift array where you can use the + or - operators to add/subtract a Double to every element of a numeric Array and return a new Array with the new elements as [Double]. Here is how I have implemented it in 2 extensions for Int and Floating point types:
extension Array where Element: BinaryInteger {
static func + (array: Self, num: Double) -> [Double]
{
return array.map{Double($0) + num}
}
static func - (array: Self, num: Double) -> [Double]
{
return array.map{Double($0) - num}
}
}
extension Array where Element: BinaryFloatingPoint {
static func + (array: Self, num: Double) -> [Double]
{
return array.map{Double($0) + num}
}
static func - (array: Self, num: Double) -> [Double]
{
return array.map{Double($0) - num}
}
}
As you can see there is a lot of duplicate code here. Is there a better way to implement this?
I tried this but it doesn't work:
extension Array where Element: Numeric {
static func + (array: Self, num: Double) -> [Double]
{
return array.map{Double($0) + num}
}
static func - (array: Self, num: Double) -> [Double]
{
return array.map{Double($0) - num}
}
}
The compiler complains at line Double($0) since Double doesn't have initializer for Numeric.
Solution 1:[1]
Why use Double at all? You're just introducing potential precision issues for integer types that have perfect precision over integers
extension Array where Element: Numeric {
static func + (array: Self, num: Element) -> [Element] {
return array.map { $0 + num }
}
static func - (array: Self, num: Element) -> [Element] {
return array.map { $0 - num }
}
}
print([1, 2, 3] + 10) // => [11, 12, 13]
Solution 2:[2]
I decided to check type of Element and force typecast instead:
extension Array where Element: Numeric {
static func + (array: Self, num: Decimal) -> [Decimal]
{
if let first = array.first {
switch first {
case is Int:
return array.map{Decimal($0 as! Int) + num}
case is Double:
return array.map{Decimal($0 as! Double) + num}
case is Decimal:
return array.map{$0 as! Decimal + num}
default:
break
}
}
return []
}
static func - (array: Self, num: Decimal) -> [Decimal]
{
if let first = array.first {
switch first {
case is Int:
return array.map{Decimal($0 as! Int) - num}
case is Double:
return array.map{Decimal($0 as! Double) - num}
case is Decimal:
return array.map{$0 as! Decimal - num}
default:
break
}
}
return []
}
static func / (array: Self, num: Decimal) -> [Decimal]
{
if let first = array.first {
switch first {
case is Int:
return array.map{Decimal($0 as! Int) / num}
case is Double:
return array.map{Decimal($0 as! Double) / num}
case is Decimal:
return array.map{$0 as! Decimal / num}
default:
break
}
}
return []
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Alexander |
| Solution 2 | Farid Rahmani |
