如何在向量中找到项目的索引?

Joh*_*den 75 clojure

任何想法????应该是什么?内置了吗?完成这项任务的最佳方法是什么?

(def v ["one" "two" "three" "two"])

(defn find-thing [ thing vectr ]
  (????))

(find-thing "two" v) ; ? maybe 1, maybe '(1,3), actually probably a lazy-seq
Run Code Online (Sandbox Code Playgroud)

Bri*_*per 125

内置:

user> (def v ["one" "two" "three" "two"])
#'user/v
user> (.indexOf v "two")
1
user> (.indexOf v "foo")
-1
Run Code Online (Sandbox Code Playgroud)

如果你想要所有匹配的索引的延迟seq:

user> (map-indexed vector v)
([0 "one"] [1 "two"] [2 "three"] [3 "two"])
user> (filter #(= "two" (second %)) *1)
([1 "two"] [3 "two"])
user> (map first *1)
(1 3)
user> (map first 
           (filter #(= (second %) "two")
                   (map-indexed vector v)))
(1 3)
Run Code Online (Sandbox Code Playgroud)

  • 这是被调用的vector的`indexOf`方法,而不是String的:`#<Method public int clojure.lang.APersistentVector.indexOf(java.lang.Object)>` (24认同)
  • 太好了,谢谢布赖恩,我的文档搜索器没有找到 indexOf,大概是因为它是 Java。我将不得不为此努力。 (3认同)
  • @John:是的.indexOf之前的点表示Java互操作.它在java.lang.String中调用方法'indexOf'.java.lang默认导入.有关更多示例,请参阅http://clojure.org/java_interop (2认同)

pon*_*zao 40

Stuart Halloway在这篇文章http://www.mail-archive.com/clojure@googlegroups.com/msg34159.html中给出了一个非常好的答案.

(use '[clojure.contrib.seq :only (positions)])
(def v ["one" "two" "three" "two"])
(positions #{"two"} v) ; -> (1 3)
Run Code Online (Sandbox Code Playgroud)

如果你想获取第一个值,只需使用first结果.

(first (positions #{"two"} v)) ; -> 1
Run Code Online (Sandbox Code Playgroud)

编辑:因为clojure.contrib.seq已经消失了,我用一个简单实现的例子更新了我的答案:

(defn positions
  [pred coll]
  (keep-indexed (fn [idx x]
                  (when (pred x)
                    idx))
                coll))
Run Code Online (Sandbox Code Playgroud)

  • 并不是它影响了这个答案的优点,但seq-utils现在已经改为clojure.contrib.seq. (2认同)

cgr*_*and 24

(defn find-thing [needle haystack]
  (keep-indexed #(when (= %2 needle) %1) haystack))
Run Code Online (Sandbox Code Playgroud)

但是我想警告你不要摆弄指数:通常情况下它会产生较少惯用,笨拙的Clojure.

  • 当我有那个用例--csv头文件时 - 我刚刚构建了一个映射来进行查找(假设有唯一的列标题).地图_is_然后我的函数做索引查找.(让[header-index(zipmap header-vector(iterate inc 0))] ...) (8认同)
  • 好吧,我会提出一些非常难以解决的问题.( - >"colname"header-index row)你有你的价值. (3认同)

lsh*_*lsh 13

从Clojure 1.4开始,clojure.contrib.seq(以及positions函数)不可用,因为它缺少维护者:http: //dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

clojure.contrib.seq/positions和它的依赖clojure.contrib.seq/indexed是:

(defn indexed
  "Returns a lazy sequence of [index, item] pairs, where items come
  from 's' and indexes count up from zero.

  (indexed '(a b c d))  =>  ([0 a] [1 b] [2 c] [3 d])"
  [s]
  (map vector (iterate inc 0) s))

(defn positions
  "Returns a lazy sequence containing the positions at which pred
   is true for items in coll."
  [pred coll]
  (for [[idx elt] (indexed coll) :when (pred elt)] idx))

(positions #{2} [1 2 3 4 1 2 3 4]) => (1 5)
Run Code Online (Sandbox Code Playgroud)

可在此处获取:http://clojuredocs.org/clojure_contrib/clojure.contrib.seq/positions

  • 感谢您发布此版本.从1.2开始,你也可以用(范围)替换(迭代inc 0). (2认同)

Joh*_*den 5

我试图回答自己的问题,但是Brian为我打了一个更好的答案!

(defn indices-of [f coll]
  (keep-indexed #(if (f %2) %1 nil) coll))

(defn first-index-of [f coll]
  (first (indices-of f coll)))

(defn find-thing [value coll]
  (first-index-of #(= % value) coll))

(find-thing "two" ["one" "two" "three" "two"]) ; 1
(find-thing "two" '("one" "two" "three")) ; 1

;; these answers are a bit silly
(find-thing "two" #{"one" "two" "three"}) ; 1
(find-thing "two" {"one" "two" "two" "three"}) ; nil
Run Code Online (Sandbox Code Playgroud)


Jos*_*h.F 5

这是我的贡献,使用looping 结构并nil在失败时返回。

我尽量避免循环,但这似乎适合这个问题。

(defn index-of [xs x]
  (loop [a (first xs)
         r (rest xs)
         i 0]
    (cond
      (= a x)    i
      (empty? r) nil
      :else      (recur (first r) (rest r) (inc i)))))
Run Code Online (Sandbox Code Playgroud)