如果我有一个像......这样的清单。
(def test [[1 2 3]
[4 5 6]
[7 8 9]])
我希望索引为5(这将是(1,1))我该怎么做? 所以(找到5个测试)=(1,1)
答案 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]])))