2017-10-04 197 views
0

我有一个元素列表,我使用Enum.chunk_every方法将它转换为列表列表。Elixir循环遍历矩阵

的代码是这样的:

matrix = Enum.chunk_every(list_1d, num_cols) 
Now I want to loop over the matrix and access the neighbors 

只需如果我有列表[1,2,3,4,5,6,1,2,3]它被转换成一个3×3矩阵像:

[1,2,3],[4,5,6],[1,2,3]]

现在我怎么遍历这个矩阵?如果我想访问元素的邻居呢?例如,5的邻居是2,4,6和2.

我可以看到递归是一种方式,但这将如何工作?

+0

您是否有多个两级深度列表?递归适用于任意深度的列表。另外,请说明5为什么邻居是2,4,5和2的原因? –

+0

如果要高效地在二维矩阵中随机访问,您需要(a)使其不变(使用元组),否则(b)使用每个矩阵元素的进程说明来构建相邻结构 - 这对于稀疏值是值得的矩阵。 – GavinBrelstaff

+0

@ denis.peplin我可以有一个100x100矩阵。我的意思是,如果元素是“(i,j)”,那么它的邻居就是(i + 1,j),(i-1,j)','(i,j-1)'和' (i,j + 1)' 我给出的例子有点不对。我的意思是5的邻居是2(i-1,j),4(i,j-1),6(i,j + 1)和2(i + 1,j)。 这对你有帮助吗? –

回答

1

有很多方法可以解决这个问题,我认为你应该首先考虑你的用例(矩阵的大小,矩阵的数量,访问次数等)并相应地调整你的数据结构。

尽管如此,这里是一个简单的实现(在二郎壳,我让你适应长命仙丹):

1> L = [[1,2,3], [4,5,6], [1,2,3]]. 
[[1,2,3],[4,5,6],[1,2,3]] 
2> Get = fun(I,J,L) -> 
      try 
       V = lists:nth(I,lists:nth(J,L)), 
       {ok,V} 
      catch 
       _:_ -> {error,out_of_bound} 
      end 
      end. 
#Fun<erl_eval.18.99386804> 
3> Get(1,2,L). 
{ok,4} 
4> Get(2,3,L). 
{ok,2} 
5> Get(2,4,L).  
{error,out_of_bound} 
6> Neighbor = fun(I,J,L) -> 
       [ V || {I1,J1} <- [{I,J-1},{I-1,J},{I+1,J},{I,J+1}], 
         {ok,V} <- [Get(I1,J1,L)] 
       ] 
       end.     
#Fun<erl_eval.18.99386804> 
7> Neighbor(2,2,L).                        
[2,4,6,2] 
8> Neighbor(1,2,L). 
[1,5,1] 
9> 

备注:我喜欢列表理解,你可能更愿意使用列表:在这种情况下地图。此代码效率不高,因为它解析4次以获取邻居。唯一的好处是它是“直线”的。所以应该很容易阅读。