我想知道在Clojure中比较字符和字符串的最佳(clojuresque)方法。 显然,类似的东西会返回false:
(= (first "clojure") "c")
因为 first 返回 java.lang.Character ,而“c”是单个字符串。是否存在直接比较char和string而不调用强制转换的构造?我没有找到与此不同的方法:
(= (str (first "clojure")) "c")
但我不满意。 有任何想法吗? 再见, 阿尔弗雷
答案 0 :(得分:42)
直接的String互操作怎么样?
(= (.charAt "clojure" 0) \c)
或
(.startsWith "clojure" "c")
它应该尽可能快,并且不会分配seq对象(在第二个示例中还有一个额外的字符串),为了进行比较,它会立即被丢弃。
答案 1 :(得分:23)
字符文字在Clojure中写成\a \b \c ...
,因此您只需编写
(= (first "clojure") \c)
答案 2 :(得分:6)
字符串可以直接编入索引,而不构建从那时开始的序列并获取该序列的第一个。
(= (nth "clojure" 0) \c)
=> true
nth调用此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);
}
直接有效地读取字符。
首先调用这个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)
}
为字符串(1)构建seq(构建seq非常快)然后从该seq(2)中获取第一个项目。返回后seq是垃圾。
Seqs显然是在clojure中访问任何顺序的最自觉的方式,而我根本不会敲它们。有趣的是要知道你在创造什么。通过调用first
切换到nth
的所有来电可能是过早优化的情况。 如果你想要字符串中的第100个字符,我会建议使用索引访问函数,如nth
简而言之:不要出汗小东西:)
答案 3 :(得分:2)
从根本上讲(至少在Clojure级别 - 虽然见Kotarak's answer和其他人的替代方案),你要比较两个序列:“clojure”和“c”。相等的条件是每个序列的第一个元素是相等的。所以,如果你想直接表达这一点,你可以做到
(apply = (map first ["clojure" "c"]))
或者相反,你在每对字符之间的相等比较上创建一个惰性序列,然后只取第一个元素:
(first (map = "clojure" "c"))
答案 4 :(得分:1)
您可以使用clojure.contrib.string中的take函数。或者编写自己的函数,如果经常需要,则返回第一个char。
答案 5 :(得分:0)
你可以像在第二个例子中那样使用str。这没有什么不妥。我的意思是,你可以先在“c”上调用它来使它成为一个角色,但它并没有真正有所作为。您不这样的原因有什么理由吗?通过在字符上调用str,它并没有真正为代码增加太多。
答案 6 :(得分:0)
user=> (= (subs "clojure" 0 1) "c")
true
user=> (= (str (first "clojure") "c"))
true
答案 7 :(得分:0)
这些天你不一定要使用Java互操作:
(clojure.string/starts-with? "clojure" "c")
starts-with?
只是一个薄的包装器(.startsWith
左右)。
所以现在如果你同时使用Clojure和ClojureScript,你就不必记住Java和JavaScript互操作。