clojure如何获取2d列表中项目的索引

时间:2013-09-22 02:31:29

标签: list clojure indexing

如果我有一个像......这样的清单。

(def test [[1 2 3]
           [4 5 6]
           [7 8 9]])

我希望索引为5(这将是(1,1))我该怎么做? 所以(找到5个测试)=(1,1)

5 个答案:

答案 0 :(得分:8)

使用list comprehension(for)可以找到所有匹配位置的列表:

(def test [[1 2 3][4 5 6][7 8 9]])

(for [[x row] (map-indexed vector test) 
      [y val] (map-indexed vector row) 
      :when (= 5 val)]
   [x y])
 => ([1 1])

编辑:对'for'函数使用解构工作。

答案 1 :(得分:2)

我不认为该操作有内置函数,但写一个函数应该不难。

您可以将嵌套的矢量展平为单个列表,然后搜索,获取结果索引并使用第一个嵌套矢量的长度拆分x和y坐标。

(defn find2d [data item]
  (let [n (count (first data))
        i (.indexOf (flatten data) item)]
    (if (pos? i)
      (list (quot i n) (mod i n)))))

(find2d data 5) ;=> (1 1)

答案 2 :(得分:0)

这应该做你想要的:

(defn indexof-2D [item mat]
  (letfn [(index-of-row 
           [x]
           (first (keep-indexed #(if (= item %2) %1) x)))]
    (->> mat
         (map-indexed #(vector %1 (index-of-row %2)))
         (filter last)
         first)))

现在我不知道你的用例是什么,但通常使用索引来解决clojure中的问题,这表明你可能从错误的角度解决问题。上述功能不应用于高性能矩阵计算,但除非另有考虑,否则应具有足够的性能。

答案 3 :(得分:0)

我同意mortalapeman你可能会以错误的角度接近问题。我不太了解A *搜索八个拼图,所以我不会尝试解决这个问题。

但我会在下面找到2d列表的索引:

(defn indexof [y xs]
  (last (find (clojure.set/map-invert (map-indexed vector xs)) y)))

(let [i (indexof 5 (flatten test))] 
  [(int (/ i 3)) (mod i 3)])

我定义了一个函数indexof来查找给定序列中元素的索引。该函数将首先创建索引和值的向量。然后反转结果,以便您有一个索引值的映射。请注意,只有列表中包含唯一元素时,此功能才有效。我假设你的问题中的数字是唯一的(如果我错了,请纠正我)。

后面的clojure语句将展平列表并找到给定元素的索引并将索引转换为2d索引。

答案 4 :(得分:0)

作为一种通用解决方案,假设您最终想要嵌套序列的所有元素的索引,您可以使用以下方法创建其索引的所有元素的映射:

(defn mat->map
  [mat]
  (into {} (for [[i row] (map-indexed vector mat)
                 [j key] (map-indexed vector row)]
             [key [i j]])))