Fico feliz que alguém não tenha medo de fazer algumas perguntas básicas.
Octopusgrabbus
4
+1 - parte do desafio é que os documentos do Clojure às vezes não abordam essas questões "básicas" que consideramos óbvias em outros idiomas. (Eu tive a mesma pergunta três anos depois e encontrei isso).
Glenn
3
@octopusgrabbus - Gostaria de saber "por que" as pessoas têm medo de fazer perguntas básicas?
appshare.co 26/01
1
@Zubair, supõe-se que as coisas básicas já foram explicadas em algum lugar, então você provavelmente ignorou algo e sua pergunta será rebaixada por "nenhum esforço de pesquisa".
Al.G.
1
Para quem vem aqui do Google olhando para converter "9"em 9, esta é a melhor coisa que funcionou para mim: (Integer. "9").
weltschmerz
Respostas:
79
Isso funcionará em 10px oupx10
(defn parse-int [s](Integer. (re-find #"\d+" s )))
ele analisará o primeiro dígito contínuo apenas para
Boa resposta! Isso é melhor do que usar read-string na minha opinião. Mudei minha resposta para usar sua técnica. Também fiz algumas pequenas alterações.
Benjamin Atkin
isso me dáException in thread "main" java.lang.ClassNotFoundException: Integer.,
maazza 31/03
83
Nova resposta
Eu gosto mais da resposta do snrobot. O uso do método Java é mais simples e mais robusto do que o uso de string de leitura para este caso de uso simples. Fiz algumas pequenas alterações. Como o autor não descartou números negativos, ajustei-o para permitir números negativos. Eu também fiz isso, requer que o número comece no início da string.
Eu gosto mais da sua resposta - pena que isso não seja fornecido pela biblioteca principal do clojure. Uma crítica menor - tecnicamente, você ifdeve ser uma, whenjá que não há mais nenhum bloqueio no seu DNS.
quux00
1
Sim, por favor, não pare de ler após o primeiro ou o segundo trecho de código!
Benjamin Atkin 22/03
2
Um alerta sobre números com zeros à esquerda. read-stringinterpreta-os como octal: (read-string "08")lança uma exceção. Integer/valueOftrata-los como decimal: (Integer/valueOf "08")avalia a 8.
rubasov
Note também que read-stringlança uma exceção se você dar-lhe uma cadeia vazia ou algo como "29px"
Ilya Boyandin
Como deveria. Respondi à pergunta no título e o que as pessoas esperam quando vêem esta página, antes de responder à pergunta no corpo da pergunta. É o último trecho de código no corpo da minha resposta.
Obrigado. Isso foi útil para dividir um produto em uma sequência de dígitos.
Octopusgrabbus
3
Como estamos na área de Java para esta resposta, geralmente é aconselhável usar Integer/valueOf, em vez do construtor Integer. A classe Integer armazena em cache valores entre -128 e 127 para minimizar a criação do objeto. O Javadoc inteiro descreve isso da mesma forma que esta postagem: stackoverflow.com/a/2974852/871012
quux00
15
Isso funciona em substituição a mim, muito mais direto.
isso é ótimo para informações confiáveis, como, por exemplo, um quebra-cabeça de programação. @ jerney está certo: tenha cuidado para não usá-lo no código real.
Hraban
10
AFAIK não há solução padrão para o seu problema. Eu acho que algo como o seguinte, que usa clojure.contrib.str-utils2/replace, deve ajudar:
Não recomendado. Funcionará até que alguém o jogue 1.5... e também não faz uso da clojure.string/replacefunção interna.
tar
8
Isso não é perfeito, mas aqui está algo com filter, Character/isDigite Integer/parseInt. Ele não funcionará para números de ponto flutuante e falhará se não houver dígito na entrada; portanto, você provavelmente deve limpá-lo. Espero que haja uma maneira melhor de fazer isso que não envolva muito Java.
Também o uso da (re-seq)função pode estender o valor de retorno para uma sequência que contém todos os números existentes na sequência de entrada na ordem:
A pergunta é feita sobre a análise de uma string em um número.
(number? 0.5);;=> true
Portanto, os decimais acima também devem ser analisados.
Talvez não esteja exatamente respondendo à pergunta agora, mas, para uso geral, acho que você gostaria de ser rigoroso sobre se é um número ou não (portanto, "px" não é permitido) e deixar que o chamador lide com não-números retornando zero:
Para quem quer analisar um literal String mais normal em um número, ou seja, uma string que não possui outros caracteres não numéricos. Estas são as duas melhores abordagens:
Ao contrário do uso read-stringdo clojure.corequal não é seguro usar em entradas não confiáveis, edn/read-stringé seguro executar em entradas não confiáveis, como a entrada do usuário.
Isso geralmente é mais conveniente do que a interoperabilidade Java, se você não precisar ter controle específico dos tipos. Ele pode analisar qualquer número literal que o Clojure possa analisar, como:
"9"
em9
, esta é a melhor coisa que funcionou para mim:(Integer. "9")
.Respostas:
Isso funcionará em
10px
oupx10
ele analisará o primeiro dígito contínuo apenas para
fonte
Exception in thread "main" java.lang.ClassNotFoundException: Integer.,
Nova resposta
Eu gosto mais da resposta do snrobot. O uso do método Java é mais simples e mais robusto do que o uso de string de leitura para este caso de uso simples. Fiz algumas pequenas alterações. Como o autor não descartou números negativos, ajustei-o para permitir números negativos. Eu também fiz isso, requer que o número comece no início da string.
Além disso, descobri que Integer / parseInt analisa como decimal quando nenhuma raiz é fornecida, mesmo se houver zeros à esquerda.
Resposta antiga
Primeiro, para analisar apenas um número inteiro (já que este é um sucesso no google e é uma boa informação de plano de fundo):
Você pode usar o leitor :
Você pode verificar se é um número depois de ler:
Não tenho certeza se a entrada do usuário pode ser confiável pelo leitor de clojure para que você possa verificar antes de ler também:
Eu acho que prefiro a última solução.
E agora, para sua pergunta específica. Para analisar algo que começa com um número inteiro, como
29px
:fonte
if
deve ser uma,when
já que não há mais nenhum bloqueio no seu DNS.read-string
interpreta-os como octal:(read-string "08")
lança uma exceção.Integer/valueOf
trata-los como decimal:(Integer/valueOf "08")
avalia a 8.read-string
lança uma exceção se você dar-lhe uma cadeia vazia ou algo como "29px"fonte
Integer/valueOf
, em vez do construtor Integer. A classe Integer armazena em cache valores entre -128 e 127 para minimizar a criação do objeto. O Javadoc inteiro descreve isso da mesma forma que esta postagem: stackoverflow.com/a/2974852/871012Isso funciona em substituição a mim, muito mais direto.
(sequência de leitura "123")
=> 123
fonte
read-string
pode executar código por docs: clojuredocs.org/clojure.core/read-stringAFAIK não há solução padrão para o seu problema. Eu acho que algo como o seguinte, que usa
clojure.contrib.str-utils2/replace
, deve ajudar:fonte
1.5
... e também não faz uso daclojure.string/replace
função interna.Isso não é perfeito, mas aqui está algo com
filter
,Character/isDigit
eInteger/parseInt
. Ele não funcionará para números de ponto flutuante e falhará se não houver dígito na entrada; portanto, você provavelmente deve limpá-lo. Espero que haja uma maneira melhor de fazer isso que não envolva muito Java.fonte
Eu provavelmente adicionaria algumas coisas aos requisitos:
Talvez algo como:
e então talvez pontos de bônus por tornar esse um método múltiplo que permita um padrão fornecido pelo usuário diferente de 0.
fonte
Expandindo a resposta do snrobot:
Esta versão retorna nulo se não houver dígitos na entrada, em vez de gerar uma exceção.
Minha pergunta é se é aceitável abreviar o nome para "str-> int" ou se coisas assim devem sempre ser totalmente especificadas.
fonte
Também o uso da
(re-seq)
função pode estender o valor de retorno para uma sequência que contém todos os números existentes na sequência de entrada na ordem:(defn convert-to-int [s] (->> (re-seq #"\d" s) (apply str) (Integer.)))
(convert-to-int "10not123")
=>10123
(type *1)
=>java.lang.Integer
fonte
A pergunta é feita sobre a análise de uma string em um número.
Portanto, os decimais acima também devem ser analisados.
Talvez não esteja exatamente respondendo à pergunta agora, mas, para uso geral, acho que você gostaria de ser rigoroso sobre se é um número ou não (portanto, "px" não é permitido) e deixar que o chamador lide com não-números retornando zero:
E se os flutuadores forem problemáticos para o seu domínio, em vez de
Float/parseFloat
colocarbigdec
ou algo mais.fonte
Para quem quer analisar um literal String mais normal em um número, ou seja, uma string que não possui outros caracteres não numéricos. Estas são as duas melhores abordagens:
Usando interoperabilidade Java:
Isso permite controlar com precisão o tipo em que você deseja analisar o número, quando isso for importante para o seu caso de uso.
Usando o leitor Clojure EDN:
Ao contrário do uso
read-string
doclojure.core
qual não é seguro usar em entradas não confiáveis,edn/read-string
é seguro executar em entradas não confiáveis, como a entrada do usuário.Isso geralmente é mais conveniente do que a interoperabilidade Java, se você não precisar ter controle específico dos tipos. Ele pode analisar qualquer número literal que o Clojure possa analisar, como:
Lista completa aqui: https://www.rubberducking.com/2019/05/clojure-for-non-clojure-programmers.html#numbers
fonte
Para casos simples, você pode usar apenas uma regex para extrair a primeira sequência de dígitos, como mencionado acima.
Se você tiver uma situação mais complicada, poderá usar a biblioteca InstaParse:
fonte
(t/refer-tupelo)
vez de fazer o usuário fazer(:require [tupelo.core :refer :all])
?refer-tupelo
é modelado depoisrefer-clojure
, na medida em que não inclui tudo do jeito que(:require [tupelo.core :refer :all])
faz.