4

如果我有一个像...

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

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

4

5 回答 5

10

使用列表推导(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”函数。

于 2013-09-24T22:37:06.460 回答
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)
于 2013-09-22T02:45:22.800 回答
0

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

(defn mat->map
  [mat]
  (into {} (for [[i row] (map-indexed vector mat)
                 [j key] (map-indexed vector row)]
             [key [i j]])))
于 2013-09-22T11:12:40.753 回答
0

我同意 mortalapeman 的观点,即您可能以错误的角度处理问题。我对八谜题的 A* 搜索知之甚少,所以我不会尝试解决这个问题。

但我会接近找到一个二维列表的索引,如下所示:

(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 索引。

于 2013-09-22T08:03:26.563 回答
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 中的问题表明您可能从错误的角度处理问题。上面的函数不应该用于高性能矩阵计算,但除非另有考虑,否则它具有足够的性能。

于 2013-09-22T03:08:20.540 回答