Je suis heureux que quelqu'un n'ait pas peur de poser des questions de base.
octopusgrabbus
4
+1 - une partie du défi est que les documents Clojure ne répondent parfois pas à ces questions «basiques» que nous tenons pour acquises dans d'autres langues. (J'ai eu la même question 3 ans plus tard et j'ai trouvé ça).
Glenn
3
@octopusgrabbus - Je serais intéressé de savoir "pourquoi" les gens ont peur de poser des questions de base?
appshare.co
1
@Zubair il est supposé que les choses de base sont déjà expliquées quelque part donc vous avez probablement oublié quelque chose et votre question sera déclassée pour "aucun effort de recherche".
Al.G.
1
Pour ceux qui viennent ici de Google qui cherchent à convertir "9"en 9, c'est la meilleure chose qui a fonctionné pour moi: (Integer. "9").
weltschmerz
Réponses:
79
Cela fonctionnera sur 10pxoupx10
(defn parse-int [s](Integer. (re-find #"\d+" s )))
il analysera le premier chiffre continu uniquement ainsi
Bonne réponse! C'est mieux que d'utiliser read-string à mon avis. J'ai changé ma réponse pour utiliser votre technique. J'ai également apporté quelques petits changements.
Benjamin Atkin
cela me donneException in thread "main" java.lang.ClassNotFoundException: Integer.,
maazza
83
Nouvelle réponse
J'aime mieux la réponse de snrobot. L'utilisation de la méthode Java est plus simple et plus robuste que l'utilisation de la chaîne de lecture pour ce cas d'utilisation simple. J'ai fait quelques petits changements. Puisque l'auteur n'a pas exclu les nombres négatifs, je l'ai ajusté pour autoriser les nombres négatifs. Je l'ai également fait pour que le numéro commence au début de la chaîne.
J'aime mieux votre réponse - dommage que cela ne soit pas fourni par la bibliothèque principale de clojure. Une critique mineure - techniquement, vous ifdevriez être un whencar il n'y a pas d'autre bloc dans votre fns.
quux00
1
Ouais, n'arrêtez pas de lire après le premier ou le deuxième extrait de code!
Benjamin Atkin
2
Un heads-up sur les nombres avec des zéros non significatifs. read-stringles interprète comme octaux: (read-string "08")lève une exception. Integer/valueOfles traite comme des nombres décimaux: donne la valeur (Integer/valueOf "08")8.
rubasov
Notez également que read-stringlève une exception si vous lui donnez une chaîne vide ou quelque chose comme "29px"
Ilya Boyandin
Comme il se doit. J'ai répondu à la question dans le titre et ce à quoi les gens s'attendent lorsqu'ils voient cette page, avant de répondre à la question dans le corps de la question. C'est le dernier extrait de code dans le corps de ma réponse.
Merci. Cela m'a aidé à diviser un produit en une séquence de chiffres.
octopusgrabbus
3
Puisque nous sommes dans le pays Java pour cette réponse, il est généralement conseillé d'utiliser Integer/valueOf, plutôt que le constructeur Integer. La classe Integer met en cache les valeurs comprises entre -128 et 127 pour minimiser la création d'objets. Le Javadoc entier décrit cela comme le fait cet article: stackoverflow.com/a/2974852/871012
quux00
15
Cela fonctionne en réponse pour moi, beaucoup plus simple.
c'est idéal pour les entrées fiables, comme par exemple un puzzle de programmation. @jerney a raison: veillez à ne pas l'utiliser dans le code réel.
hraban
10
AFAIK il n'y a pas de solution standard à votre problème. Je pense que quelque chose comme ce qui suit, qui utilise clojure.contrib.str-utils2/replace, devrait aider:
Non recommandé. Cela fonctionnera jusqu'à ce que quelqu'un le lance 1.5... et il n'utilise pas non plus la clojure.string/replacefonction intégrée.
tar
8
Ce n'est pas parfait, mais voici quelque chose avec filter, Character/isDigitet Integer/parseInt. Cela ne fonctionnera pas pour les nombres à virgule flottante et échouera s'il n'y a pas de chiffre dans l'entrée, vous devriez donc probablement le nettoyer. J'espère qu'il existe une meilleure façon de faire cela qui n'implique pas autant de Java.
Cette version renvoie nil s'il n'y a pas de chiffres dans l'entrée, plutôt que de lever une exception.
Ma question est de savoir s'il est acceptable d'abréger le nom en "str-> int", ou si des choses comme celle-ci doivent toujours être entièrement spécifiées.
L'utilisation de la (re-seq)fonction peut également étendre la valeur de retour à une chaîne contenant tous les nombres existants dans la chaîne d'entrée dans l'ordre:
La question porte sur l'analyse d'une chaîne en un nombre.
(number? 0.5);;=> true
Donc, à partir des décimales ci-dessus, il faut également analyser.
Peut-être ne répond pas exactement à la question maintenant, mais pour un usage général, je pense que vous voudriez être strict quant à savoir s'il s'agit d'un nombre ou non (donc "px" n'est pas autorisé) et laisser l'appelant gérer les non-nombres en renvoyant nil:
Pour tous ceux qui cherchent à analyser un littéral String plus normal en un nombre, c'est-à-dire une chaîne qui n'a pas d'autres caractères non numériques. Voici les deux meilleures approches:
Contrairement à l'utilisation read-stringde clojure.corequi n'est pas sûre à utiliser sur une entrée non approuvée, elle edn/read-stringpeut être exécutée en toute sécurité sur une entrée non approuvée telle que l'entrée utilisateur.
C'est souvent plus pratique que l'interopérabilité Java si vous n'avez pas besoin de contrôler spécifiquement les types. Il peut analyser n'importe quel nombre littéral que Clojure peut analyser, tel que:
Aussi, juste une question curieuse: pourquoi utilisez-vous (t/refer-tupelo)au lieu de faire faire à l'utilisateur (:require [tupelo.core :refer :all])?
Qwerp-Derp
refer-tupeloest calqué sur le modèle refer-clojure, en ce sens qu'il n'inclut pas tout ce qu'il (:require [tupelo.core :refer :all])fait.
"9"
en9
, c'est la meilleure chose qui a fonctionné pour moi:(Integer. "9")
.Réponses:
Cela fonctionnera sur
10px
oupx10
il analysera le premier chiffre continu uniquement ainsi
la source
Exception in thread "main" java.lang.ClassNotFoundException: Integer.,
Nouvelle réponse
J'aime mieux la réponse de snrobot. L'utilisation de la méthode Java est plus simple et plus robuste que l'utilisation de la chaîne de lecture pour ce cas d'utilisation simple. J'ai fait quelques petits changements. Puisque l'auteur n'a pas exclu les nombres négatifs, je l'ai ajusté pour autoriser les nombres négatifs. Je l'ai également fait pour que le numéro commence au début de la chaîne.
De plus, j'ai trouvé que Integer / parseInt analyse comme décimal lorsqu'aucune base n'est donnée, même s'il y a des zéros non significatifs.
Ancienne réponse
Tout d'abord, pour analyser juste un entier (puisqu'il s'agit d'un hit sur google et que ce sont de bonnes informations de base):
Vous pouvez utiliser le lecteur :
Vous pouvez vérifier qu'il s'agit d'un nombre après sa lecture:
Je ne suis pas sûr que l'entrée utilisateur puisse être approuvée par le lecteur clojure afin que vous puissiez également vérifier avant de la lire:
Je pense que je préfère la dernière solution.
Et maintenant, à votre question spécifique. Pour analyser quelque chose qui commence par un entier, comme
29px
:la source
if
devriez être unwhen
car il n'y a pas d'autre bloc dans votre fns.read-string
les interprète comme octaux:(read-string "08")
lève une exception.Integer/valueOf
les traite comme des nombres décimaux: donne la valeur(Integer/valueOf "08")
8.read-string
lève une exception si vous lui donnez une chaîne vide ou quelque chose comme "29px"la source
Integer/valueOf
, plutôt que le constructeur Integer. La classe Integer met en cache les valeurs comprises entre -128 et 127 pour minimiser la création d'objets. Le Javadoc entier décrit cela comme le fait cet article: stackoverflow.com/a/2974852/871012Cela fonctionne en réponse pour moi, beaucoup plus simple.
(chaîne de lecture "123")
=> 123
la source
read-string
peut exécuter du code selon la documentation: clojuredocs.org/clojure.core/read-stringAFAIK il n'y a pas de solution standard à votre problème. Je pense que quelque chose comme ce qui suit, qui utilise
clojure.contrib.str-utils2/replace
, devrait aider:la source
1.5
... et il n'utilise pas non plus laclojure.string/replace
fonction intégrée.Ce n'est pas parfait, mais voici quelque chose avec
filter
,Character/isDigit
etInteger/parseInt
. Cela ne fonctionnera pas pour les nombres à virgule flottante et échouera s'il n'y a pas de chiffre dans l'entrée, vous devriez donc probablement le nettoyer. J'espère qu'il existe une meilleure façon de faire cela qui n'implique pas autant de Java.la source
J'ajouterais probablement quelques éléments aux exigences:
Peut-être quelque chose comme:
et puis peut-être des points bonus pour en faire une méthode multiple qui permet une valeur par défaut fournie par l'utilisateur autre que 0.
la source
Extension de la réponse de snrobot:
Cette version renvoie nil s'il n'y a pas de chiffres dans l'entrée, plutôt que de lever une exception.
Ma question est de savoir s'il est acceptable d'abréger le nom en "str-> int", ou si des choses comme celle-ci doivent toujours être entièrement spécifiées.
la source
L'utilisation de la
(re-seq)
fonction peut également étendre la valeur de retour à une chaîne contenant tous les nombres existants dans la chaîne d'entrée dans l'ordre:(defn convert-to-int [s] (->> (re-seq #"\d" s) (apply str) (Integer.)))
(convert-to-int "10not123")
=>10123
(type *1)
=>java.lang.Integer
la source
La question porte sur l'analyse d'une chaîne en un nombre.
Donc, à partir des décimales ci-dessus, il faut également analyser.
Peut-être ne répond pas exactement à la question maintenant, mais pour un usage général, je pense que vous voudriez être strict quant à savoir s'il s'agit d'un nombre ou non (donc "px" n'est pas autorisé) et laisser l'appelant gérer les non-nombres en renvoyant nil:
Et si les flottants sont problématiques pour votre domaine au lieu de
Float/parseFloat
putbigdec
ou autre chose.la source
Pour tous ceux qui cherchent à analyser un littéral String plus normal en un nombre, c'est-à-dire une chaîne qui n'a pas d'autres caractères non numériques. Voici les deux meilleures approches:
Utilisation de l'interopérabilité Java:
Cela vous permet de contrôler précisément le type dans lequel vous souhaitez analyser le nombre, lorsque cela compte pour votre cas d'utilisation.
Utilisation du lecteur Clojure EDN:
Contrairement à l'utilisation
read-string
declojure.core
qui n'est pas sûre à utiliser sur une entrée non approuvée, elleedn/read-string
peut être exécutée en toute sécurité sur une entrée non approuvée telle que l'entrée utilisateur.C'est souvent plus pratique que l'interopérabilité Java si vous n'avez pas besoin de contrôler spécifiquement les types. Il peut analyser n'importe quel nombre littéral que Clojure peut analyser, tel que:
Liste complète ici: https://www.rubberducking.com/2019/05/clojure-for-non-clojure-programmers.html#numbers
la source
Pour les cas simples, vous pouvez simplement utiliser une expression régulière pour extraire la première chaîne de chiffres comme mentionné ci-dessus.
Si vous avez une situation plus compliquée, vous souhaiterez peut-être utiliser la bibliothèque InstaParse:
la source
(t/refer-tupelo)
au lieu de faire faire à l'utilisateur(:require [tupelo.core :refer :all])
?refer-tupelo
est calqué sur le modèlerefer-clojure
, en ce sens qu'il n'inclut pas tout ce qu'il(:require [tupelo.core :refer :all])
fait.