En Clojure comment puis-je convertir une Chaîne en nombre?
J'ai des chaînes différentes, certains comme "45", certains, comme "45px". Comment je convertir à la fois de celles-ci au nombre de 45?
- Je suis content que quelqu'un n'est pas peur de poser des questions de base.
- +1 - une partie de la difficulté est que la Clojure docs parfois de ne pas répondre à ces "de base" des questions que nous tenons pour acquis dans d'autres langues. (J'ai eu la même question 3 ans plus tard et a trouvé ce).
- Je serais intéressé de savoir "pourquoi" les gens ont peur de poser des questions de base?
- il est censé choses de base sont déjà expliqué quelque part donc, vous avez probablement oublié quelque chose et votre question sera downvoted pour "aucun effort de recherche".
- Oui, je pense que vous avez raison. J'ai fait des recherches et ce n'arrivais pas à trouver la réponse de n'importe où à l'époque. Si vous pouviez m'envoyer un lien où il a été expliqué puis que serait apprécié
Vous devez vous connecter pour publier un commentaire.
Cela fonctionnera sur
10px
oupx10
il analyse la première continue des chiffres uniquement
Nouvelle réponse
J'aime snrobot la réponse de mieux. À l'aide de la méthode Java est plus simple et plus robuste que d'utiliser la lecture de la chaîne pour ce cas simple d'utilisation. J'ai fait quelques petites modifications. Étant donné que l'auteur n'exclut pas les nombres négatifs, j'ai ajusté pour permettre les nombres négatifs. J'ai aussi fait en sorte qu'elle exige le nombre de départ au début de la chaîne.
En outre, j'ai trouvé que Entier/parseInt s'analyse comme décimal lorsque le pas de base est donnée, même si il y a des zéros à gauche.
Vieille réponse
Tout d'abord, analyser simplement un entier (puisque c'est un coup sur google et c'est bon arrière-plan de l'information):
Vous pouvez utiliser le lecteur:
Vous pouvez vérifier que c'est un numéro après l'avoir lu:
Je ne suis pas sûr si la saisie de l'utilisateur peuvent être approuvées par le clojure lecteur ainsi, vous pouvez vérifier avant de la lire ainsi:
Je pense que je préfère la dernière solution.
Et maintenant, à votre question. Pour analyser quelque chose qui commence par un entier, comme
29px
:if
devrait être unwhen
puisqu'il n'existe pas d'autre bloc dans votre programme pnr.read-string
interprète comme octal:(read-string "08")
déclenche une exception.Integer/valueOf
traite comme décimal:(Integer/valueOf "08")
évalue à 8.read-string
lève une exception si vous lui donnez une chaîne vide ou quelque chose comme "29px"10px
Integer/valueOf
, plutôt que de l'Entier constructeur. La classe Integer caches des valeurs comprises entre -128 et 127 à minimiser la création de l'objet. L'Entier Javadoc décrit ce que fait ce post: stackoverflow.com/a/2974852/871012Cela fonctionne dans repl pour moi, beaucoup plus simple.
(lire-chaîne "123")
=> 123
read-string
peut exécuter du code par la documentation: clojuredocs.org/clojure.core/read-stringAutant que je sache, il n'y a pas de solution standard pour votre problème. Je pense que quelque chose comme le suivant, qui utilise
clojure.contrib.str-utils2/remplacez
, devrait aider:1.5
à elle...et il ne fait pas de l'utilisation de l'intégré dansclojure.string/replace
fonction.Ce n'est pas parfait, mais voici quelque chose avec
filter
,Character/isDigit
etInteger/parseInt
. Il ne fonctionnera pas pour les nombres à virgule flottante et il échoue, si il n'y a pas de chiffres dans l'entrée, de sorte que vous devriez nettoyer. J'espère qu'il y a une jolie manière de faire qui n'implique pas autant de Java.La question porte sur l'analyse d'une chaîne de caractères en un nombre.
Donc à partir du dessus de décimales doit être analysée en tant que bien.
Peut-être pas exactement la réponse à la question maintenant, mais pour un usage général, je pense que vous voulez être rigoureux quant à savoir si c'est un nombre ou non (donc "px" ne sont pas permis) et de laisser l'appelant omet de numéros en retournant néant:
Et si les Flotteurs sont problématiques pour votre nom de domaine au lieu de
Float/parseFloat
mettrebigdec
ou quelque chose d'autre.Je serais probablement ajouter quelques choses aux exigences:
Peut-être quelque chose comme:
et puis peut-être des points de bonus pour en faire une multi-méthode qui permet à un utilisateur fourni par défaut autre que 0.
Expansion sur snrobot réponse:
Cette versions retourne nil si il n'existe pas de chiffres dans l'entrée, plutôt que de lever une exception.
Ma question est de savoir si c'est acceptable pour abréger le nom de "str->int", ou si des choses comme cela devrait toujours être entièrement spécifié.
Également à l'aide de
(re-seq)
fonction peut étendre la valeur de retour d'une chaîne de caractères 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
Pour les cas simples, vous pouvez utiliser une expression régulière pour sortir la première chaîne de chiffres mentionnés ci-dessus.
Si vous avez une situation plus compliquée, vous pouvez utiliser le InstaParse bibliothèque:
(t/refer-tupelo)
au lieu de se faire à l'utilisateur de faire(:require [tupelo.core :refer :all])
?refer-tupelo
est modélisé d'aprèsrefer-clojure
, en ce qu'elle ne comprend pas tout le chemin(:require [tupelo.core :refer :all])
n'.Pour quiconque cherche à analyser un plus normal littéral de Chaîne en un nombre, c'est une chaîne qui n'a pas d'autres non caractères numériques. Ce sont les deux meilleures approches:
À l'aide de Java interop:
Cela vous permet de contrôler avec précision le type que vous souhaitez analyser le nombre de, lors de votre cas d'utilisation.
À l'aide de la Clojure EDN lecteur:
Contrairement à l'utilisation de
read-string
declojure.core
ce qui n'est pas sûr à utiliser sur les autres entrées,edn/read-string
est sûr de courir sur les autres intrants tels que la saisie de l'utilisateur.C'est souvent plus pratique que le Java interop si vous n'avez pas besoin d'avoir de contrôle spécifiques à des types. Il peut analyser n'importe quel nombre littéral de Clojure peut analyser comme:
Liste complète ici: https://www.rubberducking.com/2019/05/clojure-for-non-clojure-programmers.html#numbers