어떤 아이디어 ????
가 있어야합니까? 내장이 있습니까? 이 작업을 수행하는 가장 좋은 방법은 무엇입니까?
(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
어떤 아이디어 ????
가 있어야합니까? 내장이 있습니까? 이 작업을 수행하는 가장 좋은 방법은 무엇입니까?
(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
답변:
내장 :
user> (def v ["one" "two" "three" "two"])
#'user/v
user> (.indexOf v "two")
1
user> (.indexOf v "foo")
-1
모든 경기에 대해 지연된 인덱스 시퀀스를 원하는 경우 :
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)
indexOf
호출되는 것은 String이 아니라 벡터의 메소드입니다.#<Method public int clojure.lang.APersistentVector.indexOf(java.lang.Object)>
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)
첫 번째 값을 얻으 first
려면 결과에 사용 하십시오.
(first (positions #{"two"} v)) ; -> 1
편집 : clojure.contrib.seq
사라졌기 때문에 간단한 구현의 예로 내 대답을 업데이트했습니다.
(defn positions
[pred coll]
(keep-indexed (fn [idx x]
(when (pred x)
idx))
coll))
clojure.contib.seq
clojure 1.6에서 어디서 얻을 수 있습니까? 목록에 라이브러리 없음 : dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go
positions
.
(defn find-thing [needle haystack]
(keep-indexed #(when (= %2 needle) %1) haystack))
그러나 나는 당신에게 인덱스를 조작하는 것에 대해 경고하고 싶습니다. 대부분은 덜 관용적이고 어색한 Clojure를 생성 할 것입니다.
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)
여기에서 사용 가능 : http://clojuredocs.org/clojure_contrib/clojure.contrib.seq/positions
나는 내 질문에 답하려고했지만 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
최근에 색인을 여러 번 찾아야했거나 문제에 접근하는 다른 방법을 찾는 것보다 쉬웠 기 때문에 선택했습니다. 그 과정에서 Clojure 목록에 .indexOf (Object object, int start) 메서드가 없다는 것을 발견했습니다. 나는 다음과 같이 문제를 처리했습니다.
(defn index-of
"Returns the index of item. If start is given indexes prior to
start are skipped."
([coll item] (.indexOf coll item))
([coll item start]
(let [unadjusted-index (.indexOf (drop start coll) item)]
(if (= -1 unadjusted-index)
unadjusted-index
(+ unadjusted-index start)))))