在Clojure中,Java interop为我们提供了.indexOf
,但ClojureScript并没有这样做。如何获取向量中项目的索引?
(def items [:a :b :c])
;; Clojure
(.indexOf items :a) ; => 0
;; ClojureScript
;; ???
答案 0 :(得分:5)
这是一个明确的递归答案。我希望能有更好的答案!
(defn index-of [s v]
(loop [idx 0 items s]
(cond
(empty? items) nil
(= v (first items)) idx
:else (recur (inc idx) (rest items)))))
答案 1 :(得分:5)
将矢量转换为数组。 http://clojuredocs.org/clojure_core/clojure.core/to-array
我不确定此处的性能是什么。 :)
cljs.user=> (.indexOf (to-array [:a :b]) :b)
=> 1
答案 2 :(得分:3)
Clojurescript似乎没有一个明确的index-of
方法(至少不是我能用合理数量的谷歌搜索找到的方法)。
对于您的示例,您可以将clojurescript数据结构映射到javascript数组并使用原生javascript .indexOf
=> (.indexOf (clj->js [:a :b :c :d]) (clj->js :c))
=> 2
但是这有两个问题,首先你必须离开持久数据结构的世界,这是使clojurescript很棒的一个重要部分,但更大的问题是它不能在引用类型上工作。 E.g。
=> (.indexOf (clj->js [{:a :b} {:c :d}]) (clj->js {:c :d}))
=> -1
因此用途有限。
在这种情况下,你自己的递归解决方案很好。如果你想要更实用的功能,你可以做到:
(defn index-of [coll v]
(let [i (count (take-while #(not= v %) coll))]
(when (or (< i (count coll))
(= v (last coll)))
i)))
答案 3 :(得分:3)
另一个选项(如果没有找到,则返回nil)
(defn index-of [coll value]
(some (fn [[idx item]] (if (= value item) idx))
(map-indexed vector coll)))