ClojureScript中向量的索引

7
在Clojure中,Java互操作性提供了.indexOf方法,但是ClojureScript没有这个方法。那么如何获取向量中项的索引呢?
(def items [:a :b :c])

;; Clojure
(.indexOf items :a) ; => 0

;; ClojureScript
;; ???
4个回答

9

这里是一个明确的递归答案。但我希望能有更好的解决方案!


(注:此段内容为关于IT技术的问题,具体问题不详)
(defn index-of [s v]
  (loop [idx 0 items s]
    (cond
      (empty? items) nil
      (= v (first items)) idx
      :else (recur (inc idx) (rest items)))))

6

在我看来,to-array 不是懒加载的。使用其他答案中的实现可能更好。尝试 (.indexOf (to-array (iterate inc 0)) 2)。 - fgui
2
这在Clojurescript中行不通,对吧?请参阅此被拒绝的错误报告:http://dev.clojure.org/jira/browse/CLJS-996在CLJS 1.7上,(.indexOf (to-array [:a :b]) :b)返回-1 - Nathan Wallace

4

另一种选项(如果未找到,则返回nil)

(defn index-of [coll value]
  (some (fn [[idx item]] (if (= value item) idx))
        (map-indexed vector coll)))

3

看起来Clojurescript没有显式的index-of方法(至少我在Google搜索了合理数量后没有找到)。

对于您的示例,您可以将Clojurescript数据结构映射到JavaScript数组,并使用本机JavaScript .indexOf

=> (.indexOf (clj->js [:a :b :c :d]) (clj->js :c))
=> 2

但这种方法存在2个问题,首先你需要离开ClojureScript最大的优点之一——持久化数据结构,而更大的问题是它无法对引用类型进行处理。例如:

=> (.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)))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接