Свифт 5, iOS 14
Я играл с дженериками в Swift, пытаясь понять их, и придумал проблему, которая кажется неразрешимой. Представьте, что у меня есть массив целых чисел разного размера.
var dindex = [Int8(1),Int16(2),Int32(3),Int64(4)] as [Any]
И я хочу преобразовать их в массив Doubles для обработки, например. Теперь карта не работает, и я не могу, кажется, просто пройтись по массиву, и мне не повезло с дженериками на данный момент...
// 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 })
}
Действительно, код по большей части даже не компилируется. В чем здесь хитрость? Это точно возможно?
Это сработает. Я преобразовал Any в тип Int
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)
}
Babar, это хорошая попытка, как говорится, решение ООПера выглядит очень объективно C'isn. Хотелось бы сделать это, не прибегая к NSNumber в идеальном мире.
@ user3069232, я согласен. Если будет опубликован еще один ответ Swifty, пожалуйста, не стесняйтесь одобрить его. Мне тоже интересно.
@OOPer, последовал твоему примеру и опубликовал ответ :)
Any
в Swift действительно сложно работать.
Пожалуйста, попробуйте это:
func convertMap(qindexIn qindexOut:[Any]) -> [Double] {
return(qindexOut.map{ ($0 as? NSNumber ?? NSNumber(0.0)).doubleValue })
}
Надеюсь, что могут быть какие-то лучшие способы.
Глядя на ответ OOPer, я понял, что это тоже работает, и, хотя он не более Swifty, возможно, он менее объективен.
func convertMap26(qindexIn qindexOut:[Any]) -> [Double] {
return(qindexOut.map{ Double("\($0)") ?? 0.0 })
}
или просто compactMap { Double("\($0)") }
это будет зависеть от того, следует ли преобразовать не число в ноль или пропустить
Какая разница Лео? Возможно, compactMap быстрее?
Как я уже сказал, это зависит от того, хочет ли OP преобразовать «a» в ноль или просто пропустить его. В этом случае, когда все они являются числами, это не будет иметь значения, и карта, вероятно, будет быстрее.
Я обновил ответ. Это будет работать, но я думаю, что решение Ooper лучше