Me alegra que alguien no tenga miedo de hacer algunas preguntas básicas.
octopusgrabbus
44
+1: parte del desafío es que los documentos de Clojure a veces no abordan estas preguntas "básicas" que damos por sentado en otros idiomas. (Tuve la misma pregunta 3 años después y encontré esto).
Glenn
3
@octopusgrabbus - ¿Me interesaría saber "por qué" la gente tiene miedo de hacer preguntas básicas?
appshare.co
1
@Zubair se supone que las cosas básicas ya se explican en alguna parte, por lo que probablemente pasó por alto algo y su pregunta será rechazada por "ningún esfuerzo de investigación".
Al.G.
1
Para los que vienen aquí desde Google busca convertir "9"en 9, esto es lo mejor que funcionó para mí: (Integer. "9").
weltschmerz
Respuestas:
79
Esto funcionará 10pxopx10
(defn parse-int [s](Integer. (re-find #"\d+" s )))
¡Buena respuesta! Esto es mejor que usar read-string en mi opinión. Cambié mi respuesta para usar tu técnica. Hice un par de pequeños cambios también.
Benjamin Atkin
esto me daException in thread "main" java.lang.ClassNotFoundException: Integer.,
maazza
83
Nueva respuesta
Me gusta más la respuesta de snrobot. Usar el método Java es más simple y más robusto que usar read-string para este caso de uso simple. Hice un par de pequeños cambios. Como el autor no descartó números negativos, lo ajusté para permitir números negativos. También lo hice para que requiera que el número comience al principio de la cadena.
Me gusta su respuesta mejor, lástima que esto no sea proporcionado por la biblioteca central de clojure. Una crítica menor: técnicamente ifdebería ser una, whenya que no hay más bloqueos en sus aletas.
quux00
1
Sí, ¡no dejes de leer después del primer o segundo fragmento de código!
Benjamin Atkin
2
Un aviso sobre los números con ceros a la izquierda. read-stringlos interpreta como octales: (read-string "08")arroja una excepción. Integer/valueOflos trata como decimales: (Integer/valueOf "08")evalúa a 8.
rubasov
Tenga en cuenta también que read-stringarroja una excepción si le da una cadena vacía o algo así como "29px"
Ilya Boyandin
Como debería. Respondí la pregunta en el título, y qué esperan las personas cuando ven esta página, antes de responder la pregunta en el cuerpo de la pregunta. Es el último fragmento de código en el cuerpo de mi respuesta.
Gracias. Esto fue útil para dividir un producto en una secuencia de dígitos.
octopusgrabbus
3
Dado que estamos en tierra de Java para esta respuesta, generalmente es aconsejable usar Integer/valueOf, en lugar del constructor Integer. La clase Integer almacena en caché valores entre -128 y 127 para minimizar la creación de objetos. El Javadoc Integer describe esto al igual que esta publicación: stackoverflow.com/a/2974852/871012
quux00 el
15
Esto funciona en respuesta para mí, mucho más directo.
Esto es ideal para entradas confiables, como por ejemplo un rompecabezas de programación. @jerney tiene razón: tenga cuidado de no usarlo en el código real.
hraban
10
AFAIK no hay una solución estándar para su problema. Creo que algo como lo siguiente, que utiliza clojure.contrib.str-utils2/replace, debería ayudar:
No recomendado. Funcionará hasta que alguien la arroje 1.5... y tampoco hace uso de la clojure.string/replacefunción incorporada.
alquitrán el
8
Esto no es perfecta, pero aquí hay algo con filter, Character/isDigity Integer/parseInt. No funcionará para números de coma flotante y falla si no hay un dígito en la entrada, por lo que probablemente debería limpiarlo. Espero que haya una mejor manera de hacer esto que no implique tanto Java.
y luego quizás puntos de bonificación por hacer de este un método múltiple que permita un valor predeterminado proporcionado por el usuario que no sea 0.
El uso de la (re-seq)función también puede extender el valor de retorno a una cadena que contiene todos los números existentes en la cadena de entrada en orden:
La pregunta se refiere a analizar una cadena en un número.
(number? 0.5);;=> true
Entonces, a partir de los decimales anteriores, también se deben analizar.
Tal vez no responda exactamente la pregunta ahora, pero para uso general, creo que le gustaría ser estricto acerca de si es un número o no (por lo tanto, "px" no está permitido) y dejar que la persona que llama maneje no números devolviendo nil:
Para cualquier otra persona que busque analizar un literal de cadena más normal en un número, es decir, una cadena que no tenga otros caracteres no numéricos. Estos son los dos mejores enfoques:
A diferencia del uso read-stringdesde el clojure.corecual no es seguro usarlo en una entrada no confiable, edn/read-stringes seguro ejecutarlo en una entrada no confiable, como la entrada del usuario.
Esto suele ser más conveniente que la interoperabilidad de Java si no necesita tener un control específico de los tipos. Puede analizar cualquier número literal que Clojure puede analizar como:
"9"
en9
, esto es lo mejor que funcionó para mí:(Integer. "9")
.Respuestas:
Esto funcionará
10px
opx10
analizará el primer dígito continuo solo para
fuente
Exception in thread "main" java.lang.ClassNotFoundException: Integer.,
Nueva respuesta
Me gusta más la respuesta de snrobot. Usar el método Java es más simple y más robusto que usar read-string para este caso de uso simple. Hice un par de pequeños cambios. Como el autor no descartó números negativos, lo ajusté para permitir números negativos. También lo hice para que requiera que el número comience al principio de la cadena.
Además, descubrí que Integer / parseInt se analiza como decimal cuando no se proporciona una raíz, incluso si hay ceros a la izquierda.
Vieja respuesta
Primero, para analizar solo un número entero (ya que este es un éxito en Google y es una buena información de fondo):
Podrías usar el lector :
Puede verificar que es un número después de leerlo:
No estoy seguro de si el lector clojure puede confiar en la entrada del usuario para que pueda verificar antes de leerla también:
Creo que prefiero la última solución.
Y ahora, a su pregunta específica. Para analizar algo que comienza con un número entero, como
29px
:fuente
if
debería ser una,when
ya que no hay más bloqueos en sus aletas.read-string
los interpreta como octales:(read-string "08")
arroja una excepción.Integer/valueOf
los trata como decimales:(Integer/valueOf "08")
evalúa a 8.read-string
arroja una excepción si le da una cadena vacía o algo así como "29px"fuente
Integer/valueOf
, en lugar del constructor Integer. La clase Integer almacena en caché valores entre -128 y 127 para minimizar la creación de objetos. El Javadoc Integer describe esto al igual que esta publicación: stackoverflow.com/a/2974852/871012Esto funciona en respuesta para mí, mucho más directo.
(cadena de lectura "123")
=> 123
fuente
read-string
puede ejecutar código según los documentos: clojuredocs.org/clojure.core/read-stringAFAIK no hay una solución estándar para su problema. Creo que algo como lo siguiente, que utiliza
clojure.contrib.str-utils2/replace
, debería ayudar:fuente
1.5
... y tampoco hace uso de laclojure.string/replace
función incorporada.Esto no es perfecta, pero aquí hay algo con
filter
,Character/isDigit
yInteger/parseInt
. No funcionará para números de coma flotante y falla si no hay un dígito en la entrada, por lo que probablemente debería limpiarlo. Espero que haya una mejor manera de hacer esto que no implique tanto Java.fuente
Probablemente agregaría algunas cosas a los requisitos:
Tal vez algo como:
y luego quizás puntos de bonificación por hacer de este un método múltiple que permita un valor predeterminado proporcionado por el usuario que no sea 0.
fuente
Ampliando la respuesta de snrobot:
Esta versión devuelve nil si no hay dígitos en la entrada, en lugar de generar una excepción.
Mi pregunta es si es aceptable abreviar el nombre a "str-> int", o si cosas como esta siempre deben especificarse por completo.
fuente
El uso de la
(re-seq)
función también puede extender el valor de retorno a una cadena que contiene todos los números existentes en la cadena de entrada en orden:(defn convert-to-int [s] (->> (re-seq #"\d" s) (apply str) (Integer.)))
(convert-to-int "10not123")
=>10123
(type *1)
=>java.lang.Integer
fuente
La pregunta se refiere a analizar una cadena en un número.
Entonces, a partir de los decimales anteriores, también se deben analizar.
Tal vez no responda exactamente la pregunta ahora, pero para uso general, creo que le gustaría ser estricto acerca de si es un número o no (por lo tanto, "px" no está permitido) y dejar que la persona que llama maneje no números devolviendo nil:
Y si los flotadores son problemáticos para su dominio en lugar de
Float/parseFloat
putbigdec
u otra cosa.fuente
Para cualquier otra persona que busque analizar un literal de cadena más normal en un número, es decir, una cadena que no tenga otros caracteres no numéricos. Estos son los dos mejores enfoques:
Usando interoperabilidad Java:
Esto le permite controlar con precisión el tipo en el que desea analizar el número, cuando eso es importante para su caso de uso.
Usando el lector Clojure EDN:
A diferencia del uso
read-string
desde elclojure.core
cual no es seguro usarlo en una entrada no confiable,edn/read-string
es seguro ejecutarlo en una entrada no confiable, como la entrada del usuario.Esto suele ser más conveniente que la interoperabilidad de Java si no necesita tener un control específico de los tipos. Puede analizar cualquier número literal que Clojure puede analizar como:
Lista completa aquí: https://www.rubberducking.com/2019/05/clojure-for-non-clojure-programmers.html#numbers
fuente
Para casos simples, puede usar una expresión regular para extraer la primera cadena de dígitos como se mencionó anteriormente.
Si tiene una situación más complicada, puede utilizar la biblioteca InstaParse:
fuente
(t/refer-tupelo)
lugar de hacer que el usuario lo haga(:require [tupelo.core :refer :all])
?refer-tupelo
sigue el modelorefer-clojure
, ya que no incluye todo lo que(:require [tupelo.core :refer :all])
hace.