List clojure如何获取2d列表中项目的索引
如果我有一个像List clojure如何获取2d列表中项目的索引,list,clojure,indexing,List,Clojure,Indexing,如果我有一个像 (def test [[1 2 3] [4 5 6] [7 8 9]]) 我想要指数5(也就是(1,1)),我该怎么做? 所以(find5test)=(1,1)我认为这个操作没有内置函数,但编写一个应该不难 您可以将嵌套向量展平到单个列表中,然后搜索、获取结果索引并使用第一个嵌套向量的长度拆分出x和y坐标 (defn find2d [data item] (let [n (count (first data)) i
(def test [[1 2 3]
[4 5 6]
[7 8 9]])
我想要指数5(也就是(1,1)),我该怎么做?
所以(find5test)=(1,1)我认为这个操作没有内置函数,但编写一个应该不难 您可以将嵌套向量展平到单个列表中,然后搜索、获取结果索引并使用第一个嵌套向量的长度拆分出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)
这应该满足您的要求:
(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中使用索引来解决问题是一个迹象,表明您可能从错误的角度来解决问题。上述函数不应用于高性能矩阵计算,但在被视为其他函数之前,其性能是足够的。我同意Mantalapeman的观点,即您可能从错误的角度处理问题。我对搜索八个谜题不太了解,所以我不会尝试解决这个问题 但我将按如下方式查找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语句将整平列表并找到给定元素的索引,并将索引转换为二维索引。作为一种通用解决方案,假设您最终需要嵌套序列中所有元素的索引,您可以使用以下方法创建所有元素到其索引的映射:
(defn mat->map
[mat]
(into {} (for [[i row] (map-indexed vector mat)
[j key] (map-indexed vector row)]
[key [i j]])))
使用列表理解(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”函数使用解构功能。我是clojure新手。我试着用这个来帮助我搜索一个8字拼图。很好,我更喜欢你的解决方案。我总是忘记与seqs.nice!关联的java方法!。但是,正如另一个答案所暗示的那样,我是否以错误的方式看待这个问题?如果你想在一个8字谜上做一个*搜索?我对涉及的算法没有很强的掌握,但我认为你不需要像那样嵌套向量。首先可以使用平面向量,然后使用row length.hmmm kk thnx作为帮助。我最初是用这个来计算从一个瓷砖槽到另一个瓷砖槽的移动次数。我想我应该为3x3矩阵找到另一种方法,因为在OP中,这很有效。但是,如果
mat
是一个大的或无限的seq,则它不会缩放。@MSmith:当然可以。如果你需要一个小矩阵的许多元素的索引,这是一个有效的解决方案,但是如果你只需要一个大矩阵的几个元素,这就不是那么多了。