比较字符和字符串的最简洁的方法是什么? (单个字符串)

发布于 2024-09-28 07:55:39 字数 334 浏览 1 评论 0原文

我想知道在 Clojure 中比较字符和字符串的最佳(clojuresque)方法是什么。 显然类似的东西会返回 false:

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

因为 first 返回 java.lang.Character 并且“c”是单个字符串。是否存在直接比较 char 和 string 而不调用强制转换的构造?我还没有找到与此不同的方法:

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

但我不满意。 有什么想法吗? 再见, 阿尔弗雷多

I was wondering about which is the best (clojuresque) way to compare a character and a string in Clojure.
Obviously something like that returns false:

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

because first returns a java.lang.Character and "c" is a single character string. Does exists a construct to compare directly char and string without invoking a cast? I haven't found a way different from this:

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

but I'm not satisfied.
Any ideas?
Bye,
Alfredo

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

奶气 2024-10-05 07:55:39

直接的字符串互操作怎么样?

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

或者

(.startsWith "clojure" "c")

它应该尽可能快,并且不会分配 seq 对象(在第二个示例中是一个附加字符串),该对象会立即被丢弃以进行比较。

How about the straight forward String interop?

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

or

(.startsWith "clojure" "c")

It should be as fast as it can get and doesn't allocate a seq object (and in your second example an additional string) which is immediately thrown away again just to do a comparison.

后eg是否自 2024-10-05 07:55:39

在 Clojure 中,字符文字的写法为 \a \b \c ...,因此您可以简单地编写

(= (first "clojure") \c)

Character literals are written \a \b \c ... in Clojure so you can simply write

(= (first "clojure") \c)
谜兔 2024-10-05 07:55:39

可以直接对字符串进行索引,而无需从那时起构建序列并获取该序列的第一个。

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

第 n 次调用此 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 是垃圾。

Seq 显然是访问 clojure 中任何顺序的最惯用的方式,我根本不会反对它们。意识到你在什么时候创造什么是很有趣的。将所有对 first 的调用替换为对 nth 的调用可能是过早优化的情况。 如果你想要字符串中的第 100 个字符,我建议使用像 nth 这样的索引访问函数

简而言之:不要为小事担心:)

strings can be directly indexed without building a sequence from then and taking the first of that sequence.

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

nth calls through to this java code:

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);
}

which efficiently reads the character directly.

first call through to this java code:

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)
}

which builds a seq for the string (1) (building a seq is really fast) and then takes the first item from that seq (2). after the return the seq is garbage.

Seqs are clearly the most idomatic way of accessing anything sequential in clojure and I'm not knocking them at all. It is interesting to be aware of what you are creating when. switching out all your calls to first with calls to nth is likely to be a case of premature optimization. if you want the 100th char in the string i would suggest using an indexed access function like nth

in short: don't sweat the small stuff :)

冷…雨湿花 2024-10-05 07:55:39

从根本上来说(至少在 Clojure 层面上——尽管参见 Kotarak 的答案 和其他人的替代方案),您正在比较两个序列:“clojure”和“c”。相等的条件是每个序列的第一个元素相等。因此,如果您想直接表达这一点,您可以这样做

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

,也可以反过来,在每对字符之间的相等比较上创建一个惰性序列,然后只取其中的第一个元素:

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

Fundamentally (at least on the Clojure level — though see Kotarak's answer and others for alternatives to this), you're comparing two sequences: "clojure" and "c". The condition of equality is that the first element of each sequence is equal. So if you want to express this directly you can do

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

or the other way around, where you create a lazy sequence over the equality comparison between each pair of characters, and just take the first element of it:

(first (map = "clojure" "c"))
锦爱 2024-10-05 07:55:39

您可以使用 clojure.contrib.string 中的 take 函数。或者编写您自己的函数来返回第一个字符(如果您经常需要的话)。

You could use the take function from clojure.contrib.string. Or write your own function that returns the first char if that's something you need frequently.

不醒的梦 2024-10-05 07:55:39

您可以只使用 str,就像在第二个示例中所做的那样。这确实没有什么问题。我的意思是,您也可以首先调用“c”以使其成为一个字符,但这不会真正产生影响。您有什么理由喜欢这个吗?通过对字符调用 str 并不会真正为您的代码添加太多内容。

You can just use str, as you did in your second example. There isn't really anything wrong with that. I mean, you could call first on "c" as well to make it a character, but it wont really make a difference. Is there any reason why you don't like this? It's not really adding much to your code by calling str on the character.

丶情人眼里出诗心の 2024-10-05 07:55:39
user=> (= (subs "clojure" 0 1) "c")
true
user=> (= (str (first "clojure") "c"))
true
user=> (= (subs "clojure" 0 1) "c")
true
user=> (= (str (first "clojure") "c"))
true
掩耳倾听 2024-10-05 07:55:39

如今,您不一定必须使用 Java 互操作:

(clojure.string/starts-with? "clojure" "c")

starts-with? 只是一个薄包装器(围绕 .startsWith)。

因此,现在如果您同时使用 Clojure 和 ClojureScript,则不必同时记住 Java 和 JavaScript 互操作。

These days you don't necessarily have to use Java interop:

(clojure.string/starts-with? "clojure" "c")

starts-with? is just a thin wrapper (around .startsWith).

So now if you use both Clojure and ClojureScript you won't have to remember both the Java and the JavaScript interop.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文