मैं वेक्टर में किसी आइटम का सूचकांक कैसे खोज सकता हूं?


84

किसी भी विचार क्या ????होना चाहिए? वहाँ एक में निर्मित है? इस कार्य को पूरा करने का सबसे अच्छा तरीका क्या होगा?

(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

ब्रायन स्पष्ट रूप से इस सवाल का जवाब है, लेकिन नीचे, क्रेगंड और एलेक्स स्टोडर्ड इस सवाल का जवाब देने के लिए कहते हैं जो मुझे पूछना चाहिए था।
जॉन लॉरेंस एस्पेन

एक अलग सवाल में सही सवाल पूछने से कुछ भी नहीं रोकता है :)
जोनाथन बेन

जवाबों:


138

निर्मित:

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

यदि आप सभी मैचों के लिए सूचकांकों के आलसी 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)

3
स्वीट, थैंक्स ब्रायन, मेरे डॉक्टर-खोजकर्ता को इंडेक्सऑफ नहीं मिला, संभवतः क्योंकि यह जावा है। मुझे इस पर काम करना होगा।
जॉन लॉरेंस एस्पेन

2
@ जॉन: हाँ। IndexOf से पहले डॉट जावा इंटरॉप इंगित करता है। इसे java.lang.String में विधि 'indexOf' कहते हैं। java.lang डिफ़ॉल्ट रूप से आयात हो जाता है। अधिक उदाहरणों के लिए clojure.org/java_interop
dermatthias

25
यह सदिश indexOfविधि है जिसे कहा जाता है, न कि स्ट्रिंग:#<Method public int clojure.lang.APersistentVector.indexOf(java.lang.Object)>
वीवीवी

44

स्टुअर्ट हल्लोवे ने इस पोस्ट में बहुत अच्छा जवाब दिया है 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))

बहुत अच्छा! यह उस तरह का जवाब है जिसकी मुझे उम्मीद थी।
जॉन लॉरेंस एस्पेन

2
ऐसा नहीं है कि यह इस उत्तर की योग्यता को प्रभावित करता है, लेकिन seq-utils को अभी clojure.contrib.seq में बदल दिया गया है।
जॉन लॉरेंस एस्पेन

1
@ जॉन, सच, मैंने इसे ठीक किया। धन्यवाद!
पोन्ज़ाओ

clojure.contib.seq1.6 में क्लोजर कहां मिलेगा ? सूची में कोई पुस्तकालय नहीं: dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go
d9k

@ d9k, "अगर एक clojure.contrib नाम स्थान यहां सूचीबद्ध है, लेकिन कोई माइग्रेशन विवरण नहीं है, तो इसका मतलब है कि किसी ने भी उस नाम स्थान को बनाए रखने के लिए स्वेच्छा से कोई प्रयास नहीं किया है।" मैंने के लिए एक उदाहरण कार्यान्वयन जोड़ा positions
पोनज़ाओ

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

लेकिन मैं आपको सूचकांकों के साथ फिडलिंग के खिलाफ चेतावनी देना चाहूंगा: सबसे अधिक बार यह कम मुहावरेदार, अजीब क्लोजर का उत्पादन करने वाला नहीं है।


ओह अच्छा 'कब'! मैं आम तौर पर सूचकांकों के बारे में सहमत हूं, लेकिन मेरे पास एक सीएसवी फ़ाइल है, और फ़ील्ड के नाम हेडर में हैं, और मैं प्रत्येक पंक्ति से फ़ील्ड "फ़ील्ड" प्राप्त करना चाहता हूं, इसलिए मैं जो कर रहा हूं वह "फ़ील्ड" दिख रहा है हेडर में, और फिर पंक्तियों को नथिंग करना। मैं interleave के साथ करने के लिए अजीब चीजों के बारे में सोच सकता हूं, लेकिन क्या एक अच्छा तरीका है जो स्पष्ट सूचकांकों का उपयोग नहीं करता है जो पठनीय हैं?
जॉन लॉरेंस एस्पेन

8
जब मेरे पास वह उपयोग-केस है - सीएसवी हेडर - मैंने केवल लुकअप करने के लिए एक नक्शा बनाया है (अद्वितीय कॉलम हेडर मानकर)। नक्शा है तो सूचकांक देखने करने के लिए मेरे कार्य करते हैं। (let [हेडर-इंडेक्स (zipmap हेडर-वेक्टर (इट्रेर्ट इंक 0)) ...)
एलेक्स स्टोडार्ड

1
वाह। आपने उस प्रश्न का उत्तर दिया जो मुझे पूछना चाहिए था!
जॉन लॉरेंस एस्पेन

3
खैर, मैंने एलेक्स के समाधान के लिए बहुत कुछ प्रस्तावित किया। (-> "colname" हेडर-इंडेक्स पंक्ति) और आपके पास आपका मूल्य है।
cgrand

14

क्लोजर के रूप में 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/formitions


2
इस संस्करण को पोस्ट करने के लिए धन्यवाद। 1.2 के बाद से आप बस (श्रेणी) के साथ इसे बदल सकते हैं (0 से अधिक)।
ड्रिनेट

6

मैं अपने ही सवाल का जवाब देने की कोशिश कर रहा था, लेकिन ब्रायन ने मुझे एक बेहतर जवाब दे दिया!

(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

3

यहाँ मेरा योगदान है, एक loopआईएनजी संरचना का उपयोग करना और 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)))))

2

मुझे हाल ही में कई बार अनुक्रमणिकाएं ढूंढनी पड़ीं या फिर मैंने चुना क्योंकि समस्या के करीब पहुंचने का एक और तरीका समझाना आसान था। जिस तरह से मुझे पता चला कि मेरी क्लोजर सूचियों में .indexOf (ऑब्जेक्ट ऑब्जेक्ट, इंट स्टार्ट) विधि नहीं थी। मैं इस तरह की समस्या से निपटा:

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

0

मैं कम-केवी के साथ जाऊंगा

(defn find-index [pred vec]
  (reduce-kv
    (fn [_ k v]
      (if (pred v)
        (reduced k)))
    nil
    vec))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.