How to convert an array of mixed sized integers in swift

Viewed 89

Swift 5, iOS 14

I have playing around with generics in Swift trying to understand them and made up a problem that seems unsolvable. Imagine I have an array of mixed sized integers.

var dindex = [Int8(1),Int16(2),Int32(3),Int64(4)] as [Any]

And I want to convert them to as array of Doubles for processing for example. Now map does not work nor am I able it seems to simply step through the array and I having no luck with generics at this point...

// does not work
func convertMap(qindexIn qindexOut:[Int]) -> [Double] {
  return(qindexOut.map({ Double($0) }))
}

// does not work
func convertMap22(qindexIn qindexOut:[Any]) -> [Double] {
  let foo:[Double] = []
  for i in qindexOut {
    foo.append(Double(i))
  }
  return(foo)
}

// does not work
func convertMap2<T: BinaryInteger>(qindexIn qindexOut:[T]) -> [Double] {
  return(qindexOut.map({ Double($0) }))
}

// this doesn't work either
func convertMap22(qindexIn qindexOut:[Any]) -> [Int] {
  return(qindexOut.compactMap { $0 as? Int })
}

Indeed the code doesn't even compile for the most part. What is the trick here? It is surely possible?

3 Answers

Any in Swift is really a hard thing to work with.

Please try this:

func convertMap(qindexIn qindexOut:[Any]) -> [Double] {
    return(qindexOut.map{ ($0 as? NSNumber ?? NSNumber(0.0)).doubleValue })
}

Hope there may be some better ways.

This will work. I casted Any to Int type

 func convertMap22(qindexIn qindexOut:[Any]) -> [Double] {
     var foo:[Double] = []
     for i in qindexOut {
     if let intValue = i as? Int{
         let doubleValue = Double(intValue)
         foo.append(doubleValue)
     }else if let intValue = i as? Int8{
         let doubleValue = Double(intValue)
         foo.append(doubleValue)
     }else if let intValue = i as? Int16{
         let doubleValue = Double(intValue)
         foo.append(doubleValue)
     }else if let intValue = i as? Int32{
         let doubleValue = Double(intValue)
         foo.append(doubleValue)
     }else if let intValue = i as? Int64{
        let doubleValue = Double(intValue)
        foo.append(doubleValue)
    }
  }
  return(foo)
}

Looking at OOPer answer gave me an idea, this works too and although isn't more Swifty perhaps is less Objective C'ish.

func convertMap26(qindexIn qindexOut:[Any]) -> [Double] {
    return(qindexOut.map{ Double("\($0)") ?? 0.0 })
}
Related