Estou tentando escrever um programa de IMC em linguagem rápida. E eu tenho esse problema: como converter uma String para um Double?
No Objective-C, posso fazer assim:
double myDouble = [myString doubleValue];
Mas como posso conseguir isso na linguagem Swift?
Respostas:
Swift 4.2+ String para Double
Você deve usar os novos inicializadores de tipo para converter entre String e tipos numéricos (Double, Float, Int). Ele retornará um tipo Opcional (Duplo?) Que terá o valor correto ou nulo se a String não for um número.
Nota: A propriedade NSString doubleValue não é recomendada porque retorna 0 se o valor não puder ser convertido (por exemplo: entrada incorreta do usuário).
Desembrulhe os valores para usá-los usando if / let
Você pode converter números e moedas formatados usando a
NumberFormatter
classeFormatos de moeda
Leia mais no meu post sobre como converter tipos String para Double (e moeda) .
fonte
Swift 2 Update Há novos initializers failable que permitem que você faça isso de maneira mais idiomática e segura (como muitas respostas têm notado, duplo valor de NSString não é muito seguro porque ele retorna 0 para valores não numéricos. Isto significa que o
doubleValue
dos"foo"
e"0"
são o mesmo.)Isso retorna um opcional; portanto, em casos como a passagem de
"foo"
ondedoubleValue
retornaria 0, o inicializador disponível retornaránil
. Você pode usar umguard
,if-let
oumap
para lidar com oOptional<Double>
Postagem original: você não precisa usar o construtor NSString como a resposta aceita propõe. Você pode simplesmente fazer a ponte dessa maneira:
fonte
- [NSString doubleValue]
éDouble
rápido, ao contrário deDouble?
(Optional<Double>
). Isso é diferente da função Swift String,toInt()
que retornaInt?
e declara nos documentos que "... aceita strings que correspondem à expressão regular" [- +]? [0-9] + "only"..toInt()
seria melhor. No entanto, essa foi mais uma resposta de como fazer exatamente a mesma coisa, mas em Swift.Double.init?(_ text: String)
um inicializador disponível agora disponível.Para uma sensação um pouco mais rápida, o uso
NSFormatter()
evita a conversão paraNSString
e retornanil
quando a sequência não contém umDouble
valor (por exemplo, "teste" não retornará0.0
).Como alternativa, estendendo o
String
tipo de Swift :e use-o como
toInt()
:Isso retorna um opcional
Double?
que precisa ser desembrulhado.Com desembrulhamento forçado:
ou com uma declaração if let:
Atualização: para localização, é muito fácil aplicar localizações ao NSFormatter da seguinte maneira:
Por fim, você pode usar
NSNumberFormatterCurrencyStyle
o formatador se estiver trabalhando com moedas em que a sequência contém o símbolo da moeda.fonte
Outra opção aqui é converter isso em um
NSString
e usar o seguinte:fonte
(swiftString as NSString).doubleValue
Aqui está um método de extensão que permite que você simplesmente chame doubleValue () em uma string Swift e receba um retorno duplo (a saída de exemplo vem primeiro)
Aqui está o método de extensão:
Nenhuma verificação de erro, mas você pode adicioná-lo se precisar.
fonte
A partir do Swift 1.1, você pode passar diretamente
String
para oconst char *
parâmetroSe você não gostar do uso suspenso
atof
:Uma ressalva: o comportamento da conversão é diferente de
NSString.doubleValue
.atof
estrtod
aceite a0x
sequência hexadecimal prefixada:Se você preferir
.doubleValue
comportamento, ainda podemos usar aCFString
ponte:fonte
NSString
.No Swift 2.0, a melhor maneira é evitar pensar como um desenvolvedor de Objective-C. Portanto, você não deve "converter uma String em um Double", mas "inicializar um Double a partir de uma String". Documento da Apple aqui: https://developer.apple.com/library/ios//documentation/Swift/Reference/Swift_Double_Structure/index.html#//apple_ref/swift/structctr/Double/s:FSdcFMSdFSSGSqSd_
É um init opcional para que você possa usar o operador coalescente nulo (??) para definir um valor padrão. Exemplo:
fonte
Double.init?(_ text: String)
tornar-se disponível no Swift 2.0. Você deveria mencionar isso. Outras respostas aqui não são porque as pessoas pensam como desenvolvedores do Objective-C, mas porque esse inicializador não estava disponível anteriormente.No SWIFT 3 , você pode usar:
Nota: - Se uma sequência contiver caracteres que não sejam dígitos numéricos ou grupos apropriados para localidade ou separadores decimais, a análise falhará. - Qualquer caractere separador de espaço à esquerda ou à direita em uma sequência é ignorado. Por exemplo, as sequências "5", "5" e "5" produzem o número 5.
Retirado da documentação: https://developer.apple.com/reference/foundation/numberformatter/1408845-number
fonte
Não vi a resposta que estava procurando. Acabei de publicar aqui o meu, para o caso de ajudar alguém. Esta resposta é válida apenas se você não precisar de um formato específico .
Swift 3
fonte
Tente o seguinte:
NOTA
Removido no Beta 5. Isso não funciona mais?
fonte
Isso se baseia na resposta de @Ryu
A solução dele é ótima, desde que você esteja em um país onde pontos são usados como separadores. Por padrão,
NSNumberFormatter
usa o código de idioma do dispositivo. Portanto, isso falhará em todos os países onde uma vírgula é usada como separador padrão (incluindo a França como @PeterK. Mencionado) se o número usar pontos como separadores (o que normalmente é o caso). Para definir o código de idioma deste NSNumberFormatter como US e, assim, usar pontos como separadores, substitua a linhacom
Portanto, o código completo se torna
Para usar isso, basta ligar
"Your text goes here".toDouble()
Isso retornará um opcional
Double?
Como o @Ryu mencionou, você pode forçar o desembrulho:
ou use uma
if let
declaração:fonte
NumberFormatter().number(from: myString)?.doubleValue
SWIFT 4
fonte
Swift 4.0
tente isso
fonte
Swift: 4 e 5
Existem duas maneiras possíveis de fazer isso:
String -> Int -> Duplo:
String -> NSString -> Duplo
Use-o como quiser, de acordo com a necessidade do código.
fonte
Por favor, verifique no playground!
A propósito, no meu Xcode
.toDouble () - não existe
.doubleValue cria valor 0.0 a partir de cadeias não numéricas ...
fonte
1
2)
Pode ser essa ajuda para você.
fonte
Como já apontado, a melhor maneira de conseguir isso é com o casting direto:
Com base nisso, é possível criar uma extensão nativa do Swift String:
Isso permite que você use diretamente:
Qual irá realizar o casting para você. Se a Apple adicionar um
doubleValue
ao String nativo, você só precisará remover a extensão e o restante do seu código será compilado automaticamente!fonte
SWIFT 3
Para limpar, hoje em dia existe um método padrão:
public init?(_ text: String)
deDouble
classe.Pode ser usado para todas as classes.
let c = Double("-1.0")
let f = Double("0x1c.6")
let i = Double("inf")
, etc.fonte
Extensão com localidade opcional
Swift 2.2
Swift 3.1
fonte
Ou você pode fazer:
fonte
Você pode usar StringEx . Ele se estende
String
a conversões de string para número, inclusivetoDouble()
.Ele verifica a string e falha se não puder ser convertido para o dobro.
Exemplo:
fonte
Swift 4
fonte
O que também funciona:
fonte
Use esse código no Swift 2.0
let strWithFloat = "78.65" let floatFromString = Double(strWithFloat)
fonte
O uso
Scanner
em alguns casos é uma maneira muito conveniente de extrair números de uma string. E é quase tão poderoso quantoNumberFormatter
quando se trata de decodificar e lidar com diferentes formatos e localizações de números. Pode extrair números e moedas com diferentes separadores decimais e de grupo.No entanto, existem problemas com separadores que podem ser concebidos como delimitadores de palavras.
Não há problema em detectar automaticamente a localidade. Observe que agruparSeparator no código de idioma francês na cadeia "Mon salaire est 9 999,99 €" não é um espaço, embora possa render exatamente como espaço (aqui não é). É por isso que o código abaixo funciona bem sem que os
!$0.isWhitespace
caracteres sejam filtrados.fonte
Acho mais legível adicionar uma extensão a String da seguinte maneira:
e então você poderia escrever seu código:
fonte
meu problema era vírgula, então eu resolvo desta maneira:
fonte
fonte
podemos usar o valor CDouble, que será obtido por myString.doubleValue
fonte