Déterminer si une chaîne est valide valeur float
Est-il un moyen de vérifier simplement si une chaîne de valeur est valide valeur flottante. L'appel de to_f sur une chaîne de convertir 0.0 si elle n'est pas une valeur numérique. Et l'utilisation de Float() lève une exception quand il est passé à une défaillance de float string qui est plus proche de ce que je veux, mais je ne veux pas la poignée d'intercepter les exceptions. Ce que je veux vraiment, c'est une méthode comme le nan? qui n'existe pas dans la classe integer, mais ça n'aide pas parce qu'un non-chaîne numérique ne peut pas être converti en float, sans être modifiés à 0,0 (à l'aide de to_f).
"a".to_f => 0.0
"a".to_f.nan? => false
Float("a") => ArgumentError: invalid value for Float(): "a"
Est-il une solution simple pour cela ou dois-je besoin d'écrire du code pour vérifier si une chaîne est valide valeur float?
Vous devez vous connecter pour publier un commentaire.
Un fait intéressant à propos de Ruby le monde est l'existence de la Rubinius projet, qui met en œuvre de Rubis et de sa bibliothèque standard pour la plupart dans le plus pur Ruby. En conséquence, ils ont un pur Ruby mise en œuvre de Noyau#Flotter, ce qui ressemble à:
Cela vous donne une expression régulière qui correspond à l'interne le travail Ruby n'lorsqu'il s'exécute Float(), mais sans exception. Donc, vous pouvez maintenant le faire:
La bonne chose à propos de cette solution est que depuis Rubinius s'exécute, et passe RubySpec, vous savez cette regex poignées de bord-cas que Ruby lui-même les poignées, et vous pouvez les appeler to_f sur la Chaîne sans aucune crainte!
Voici un moyen:
Si vous voulez éviter le singe-patch de la Chaîne, vous pouvez toujours en faire une méthode de classe de certains module de contrôle, bien sûr:
J'ai vu la discussion non résolus sur cast+exceptions vs regex et j'ai pensé que je voudrais essayer de référence de tout et de produire une réponse objective:
Ici est la source pour le meilleur des cas et le pire de chaque méthode tenté ici:
Avec les résultats suivants avec mri193:
Puisque nous avons affaire à un temps Linéaire algorithmes je pense que nous utilisons des mesures empiriques de faire des généralisations. Il est facile de voir que la regex est plus cohérente et ne fluctuent un peu en fonction de la longueur de la chaîne passée. Le casting est clairement plus rapide quand il n'y a pas d'échec, et beaucoup plus lent quand il y a des échecs.
Si l'on compare la réussite fois, nous pouvons voir que le casting dans le meilleur des cas est d'environ de 3 secondes plus vite que la regex dans le meilleur des cas. Si nous divisons ce chiffre par la quantité de temps dans le cas le pire des cas, on peut estimer le nombre de pistes qu'il faudrait pour casser même avec des exceptions, le ralentissement de la distribution vers le bas pour correspondre à la regex de vitesses. Environ 6 secondes plongé par .3 nous donne environ 20. Donc, si la performance est importante et vous vous attendez à moins de 1 au 20 de votre test à l'échec alors utilisé en fonte+exceptions.
JRuby 1.7.4 a des résultats complètement différents:
Cast n'est que légèrement plus rapide dans le meilleur des cas (environ 10%). En présumant que cette différence est approprié pour faire des généralisations(je ne pense pas qu'il l'est), alors le seuil de rentabilité se situe entre 200 et 250 fonctionne avec seulement 1 provoquer une exception.
Si les exceptions ne devraient être utilisé quand elles sont vraiment exceptionnelles, il se passe des choses, c'est une décision pour vous et votre base de code. Quand ils ne sont pas utilisés code, qu'ils sont peut être plus simple et plus rapide.
Si la performance n'est pas grave, vous devriez probablement juste après en fonction de ce que les conventions de l'équipe ou de la base de code a déjà et ignorer cet ensemble de réponses.
Umm, si vous ne voulez pas que les exceptions alors peut-être:
Depuis l'OP a demandé spécifiquement pour une solution sans exceptions. Regexp en fonction de la solution est un peu lent:
Résultats:
Essayer cette
Ce soutient
1.5
,5
,123.456
,1_000
mais pas1 000
,1,000
, etc. (par exemple, de même queString#to_f
).Source: https://github.com/ruby/ruby/blob/trunk/object.c#L2934-L2959
J'ai essayé de l'ajouter comme commentaire, mais apparemment il n'y a pas de mise en forme dans les commentaires:
d'autre part, pourquoi ne pas simplement de l'utiliser comme fonction de conversion, comme
qui est bien sûr ce que vous ne voulez pas le faire en premier lieu. Je suppose que la réponse est: "vous devez écrire votre propre fonction si vous ne voulez vraiment pas à utiliser la gestion des exceptions, mais, pourquoi le feriez-vous?"