28 votes

Quelle est la façon la plus clojuresque de comparer les caractères et la chaîne? (chaîne de caractères unique)

Je me demandais à propos de qui est le meilleur (clojuresque) pour comparer un caractère et une chaîne en Clojure. De toute évidence, quelque chose comme ça retourne false:

(= (first "clojure") "c")

parce que la première renvoie une java.lang.Caractère et "c" est une seule chaîne de caractères. Ne existe une construction de comparer directement char et string sans faire appel à un casting? Je n'ai pas trouvé un moyen différent de ce:

(= (str (first "clojure")) "c")

mais je ne suis pas satisfait. Des idées? Bye, Alfredo

42voto

kotarak Points 11177

Que diriez-vous de l'interopérabilité de chaîne simple?

 (= (.charAt "clojure" 0) \c) 

ou

 (.startsWith "clojure" "c") 

Il doit être aussi rapide que possible et ne pas allouer un objet seq (et dans votre deuxième exemple une chaîne supplémentaire) qui est immédiatement jeté à nouveau juste pour faire une comparaison.

23voto

Jonas Points 8296

Les littéraux de caractères sont écrits \a \b \c ... dans Clojure pour que vous puissiez simplement écrire

 (= (first "clojure") \c)
 

7voto

Arthur Ulfeldt Points 45059

les chaînes peuvent être indexés directement sans la construction d'une séquence à partir de là et de prendre le premier de la séquence.

(= (nth "clojure" 0) \c) 
=> true

nth des appels par le biais de ce code java:

static public Object nth(Object coll, int n){
    if(coll instanceof Indexed)
        return ((Indexed) coll).nth(n);    <-------
    return nthFrom(Util.ret1(coll, coll = null), n);
}

efficacement lit le caractère directement.

premier appel grâce à ce code java:

static public Object first(Object x){
    if(x instanceof ISeq)
        return ((ISeq) x).first();
    ISeq seq = seq(x);    <----- (1)
    if(seq == null)
        return null;
    return seq.first();   <------ (2)
}

qui construit une seq pour la chaîne (1) (bâtiment seq est vraiment très rapide) et prend alors le premier élément de cette séquence (2). après le retour de la seq est des ordures.

Seqs sont clairement les plus idomatic moyen d'accéder à quelque chose séquentielle en clojure et je ne dénigre pas du tout. Il est intéressant d'être au courant de ce que vous créez lorsque. commutation de tous vos appels à l' first appels d' nth est susceptible d'être un cas d'optimisation prématurée. si vous voulez le 100e char dans la chaîne, je voudrais suggérer à l'aide d'un accès indexé fonction comme nième

en bref: ne pas transpirer les petites choses :)

2voto

intuited Points 7763

Fondamentalement (au moins sur le Clojure niveau de bien voir Kotarak de réponse et d'autres pour des alternatives), vous êtes à la comparaison de deux séquences: "clojure" et "c". La condition de l'égalité, c'est que le premier élément de chaque séquence est égal. Donc, si vous voulez exprimer directement ce que vous pouvez faire

(apply = (map first ["clojure" "c"]))

ou, à l'inverse, lorsque vous créez un paresseux séquence sur la comparaison d'égalité entre chaque paire de caractères, et il suffit de prendre le premier élément de celui-ci:

(first (map = "clojure" "c"))

1voto

Matti Pastell Points 4244

Vous pouvez utiliser la fonction take de clojure.contrib.string . Ou écrivez votre propre fonction qui renvoie le premier caractère si c'est quelque chose dont vous avez besoin fréquemment.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X