4

私の質問は、一致が発生したベクトル行のインデックスをキャプチャするにはどうすればよいですか?以下のコードでは、何が間違っていますか?

私はベクトルのベクトルを持っています

(def v1 [[44 2 3 4 5][1 6 7 5 10][11 12 13 14 15]])

列インデックス、および比較値

(def cmp-val1 11)
(def col-idx 0)

比較でtrueが返された行インデックスを返したい。col-idx=0およびcmp-val1=11の場合、(最初のrow-num)が2を返し、1を返します。

(defn ret-match-row
    "Return the index of the row, in which the cmp-val is found.
     It is okay to increment 0."

    [in-seq cmp-val col-idx]

    (let [rn 0]
        (let [row-num
            (for [seq-row in-seq
                    :let [local-row-num (inc rn)]
                    :when (= cmp-val (nth seq-row col-idx nil))]

                local-row-num)]

            (first row-num))))

lein replから:

bene-csv.core=> (ret-match-row v1 cmp-val1 col-idx)
1
4

4 に答える 4

3

柔軟な答えは、これを3つの異なる問題に分割し、それらを構成することから得られます。

  • 求めるデータを作成する
  • 必要なデータを見つける
  • それがどのように見えるべきかを提示します。

まず、行番号を追加して行に番号を付けます

(map vector v1 (range))

次に、必要な数を含まない行を除外します。

(filter (fn [[data index]] (some #{11} data)) (map vector v1 (range)))
> ([[11 12 13 14 15] 2])

ここでは、セットが複数の値をテストできるようにするセットに含まれる入力をテストする関数であるというトリックを使用しました。

(filter (fn [[data index]] (some #{11 44} data)) (map vector v1 (range)))
> ([[44 2 3 4 5] 0] [[11 12 13 14 15] 2])

次に、一致した場所だけを知りたいので、一致したものは知りたくないので、それを除外します。

(map second (filter (fn [[data index]] (some #{11 44} data)) (map vector v1 (range))))
> (0 2)


これを素敵な関数にラップするために、次の手順を書きます。

(defn with-row-numbers [col] (map vector col (range)))
(defn find-my-rows [rows goals] 
   (filter (fn [[data index]] (some (set goals) data)) rows)) 
(defn present-rows [rows] (map second rows))

そしてそれらを構成します:

(defn ret-match-row [data rows]
  (-> data 
   (with-row-numbers) 
   (find-my-rows rows) 
   (present-rows)))

(ret-match-row v1 [11])
(2)

申し訳ありませんが、私はそれを複数の値で動作させるのを助けることができませんでした、それは習慣です。

(ret-match-row v1 [11 15 44])
> (0 2)
于 2012-05-03T23:25:52.317 に答える
3
=> (defn ret-match-row
      [coll cmp idx]
      (keep-indexed (fn [i v] (if (= cmp (get v idx)) i)) coll))

=> (ret-match-row v1 11 0)
(2)
于 2012-05-03T23:08:55.173 に答える
1

あなたが求めていることを行うには他の方法があるかもしれませんが、ループ/再帰を使用して、後の反復を実現できます。

(defn ret-match-row [rows val col-idx]                                                                              
  (loop [[row & rows] rows                                                                                          
         pos 0]                                                                                                     
    (cond                                                                                                           
      (not row)                                                                                                     
      nil                                                                                                           
      (= val (nth row col-idx))                                                                                     
      pos                                                                                                           
      :not-found                                                                                                    
      (recur rows (inc pos)))))                                                                                     

(ret-match-row [[44 2 3 4 5]                                                                                        
                [1 6 7 8 10]                                                                                        
                [11 12 13 14 15]]                                                                                   
               11                                                                                                   
               0)                                                                                                   

;; => 2

また、Clojure の不変性にも遭遇しています。(inc rn) は実際には rn を変更していません。loop/recur ソリューションも inc を使用しますが、inc の結果をループの次の繰り返しに渡します。

Clojure の for (リスト内包表記) 形式も、シーケンス内のすべての値をループし、結果として新しいシーケンスになります。for ループを実行したとしても、最初の一致だけでなく、すべての一致が検出されます。ループ/再帰の例は、最初の一致で停止します。

于 2012-05-03T23:01:49.093 に答える
0

私の見解は、clojure.contrib.seq find-firstを使用して、索引付けされています:

(defn ret-match-row [rows val col-idx]
(最初
(find-first#(= val(nth(second%)col-idx))
(インデックス付き行))))
于 2012-05-08T06:50:34.797 に答える