95 votes

Comment trouver l'index d'un élément dans un vecteur?

Des idées quoi ???? devrait être? Y a-t-il un construit? Quel serait le meilleur moyen d'accomplir cette tâche?

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

(defn find-thing [ "two" v ]
  (????))

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

153voto

Brian Carper Points 40078

Intégré:

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

Si vous voulez une liste paresseuse des index pour tous les matchs:

 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)
 

50voto

ponzao Points 7907

Stuart Halloway a donné une très belle réponse à ce post 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)

Si vous souhaitez saisir la première valeur juste utiliser first sur le résultat.

(first (positions #{"two"} v)) ; -> 1

EDIT: en clojure.contrib.seq a disparu j'ai mis à jour ma réponse avec un exemple simple de mise en œuvre:

(defn positions
  [pred coll]
  (keep-indexed (fn [idx x]
                  (when (pred x)
                    idx))
                coll))

29voto

cgrand Points 4922
 (defn find-thing [needle haystack]
  (keep-indexed #(when (= %2 needle) %1) haystack))
 

Mais je tiens à vous mettre en garde contre le fait de manipuler des indices: le plus souvent, cela produira un Clojure moins idiomatique et moins pratique.

14voto

lsh Points 314

Comme de Clojure 1.4 clojure.contrib.seq (et donc l' positions de la fonction) n'est pas disponible car il manque un responsable: http://dev.clojure.org/display/design/Where+Ne+Clojure.Contrib+Go

La source d' clojure.contrib.seq/positions et c'est la dépendance clojure.contrib.seq/indexed est:

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

Disponible ici: http://clojuredocs.org/clojure_contrib/clojure.contrib.seq/positions

7voto

J'essayais de répondre à ma propre question, mais Brian m'a battu avec une meilleure réponse!

 (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
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X