2017-04-15 23 views
0

我正在創建一個2d地圖,並希望通過預填充空值來啓動。如何在Elixir的循環中創建地圖

我知道以下不能在Elixir中工作,但這是我想要做的。

def empty_map(size_x, size_y) do 
    map = %{} 

    for x <- 1..size_x do 
    for y <- 1..size_y do 
     map = Map.put(map, {x, y}, " ") 
    end 
    end 
end 

然後我會繪製形狀到那個地圖一樣

def create_room(map, {from_x, from_y}, {width, height}) do 
    for x in from_x..(from_x + width) do 
    for y in from_x..(from_x + width) do 
     if # first line, or last line, or first col, or last col 
     map = Map.replace(map, x, y, '#') 
     else 
     map = Map.replace(map, x, y, '.') 
     end 
    end 
    end 
end 

我試圖做一個二維數組,但我認爲與協調touples平面地圖作爲鍵會更容易使用。

我知道我應該使用遞歸,但我並沒有真正理解如何優雅地完成這個場景,並且我還沒有看到一個簡單/通用的方法來實現這一點。

回答

2

你可以用兩個嵌套Enum.reduce/3這裏,通過地圖的蓄電池,而不是寫遞歸函數自己:

defmodule A do 
    def empty_map(size_x, size_y) do 
    Enum.reduce(1..size_x, %{}, fn x, acc -> 
     Enum.reduce(1..size_y, acc, fn y, acc -> 
     Map.put(acc, {x, y}, " ") 
     end) 
    end) 
    end 
end 

IO.inspect A.empty_map(3, 4) 

輸出:

%{{1, 1} => " ", {1, 2} => " ", {1, 3} => " ", {1, 4} => " ", {2, 1} => " ", 
    {2, 2} => " ", {2, 3} => " ", {2, 4} => " ", {3, 1} => " ", {3, 2} => " ", 
    {3, 3} => " ", {3, 4} => " "} 
+0

正是我需要的,謝謝!順便說一句,有一種方法來擺脫'end')括號中的位? – hakunin

+1

是的,您可以用'end'替換'reduce('with'reduce'和'end)'。當參數很長時,我更喜歡將它們寫出來,但它們是可選的。 – Dogbert

1

另一種方法是創建一個列表元組理解並將其轉換爲地圖。

iex(18)> defmodule Room do 
...(18)> def empty_map(size_x, size_y) do 
...(18)>  for x <- 1..size_x, y <- 1..size_y do 
...(18)>  {{x,y}, " "} 
...(18)>  end 
...(18)>  |> Enum.into(%{}) 
...(18)> end 
...(18)> 
...(18)> def create_room(map, {from_x, from_y}, {width, height}) do 
...(18)>  last_x = from_x + width 
...(18)>  last_y = from_y + height 
...(18)>  for x <- from_x..last_x, y <- from_y..last_y do 
...(18)>  if x == from_x or x == last_x or y == from_y or y == last_y, 
...(18)>   do: {{x, y}, "#"}, else: {{x, y}, "."} 
...(18)>  end 
...(18)>  |> Enum.into(map) 
...(18)> end 
...(18)> end 
warning: redefining module Room (current version defined in memory) 
    iex:18 

{:module, Room, 
<<70, 79, 82, 49, 0, 0, 10, 244, 66, 69, 65, 77, 69, 120, 68, 99, 0, 0, 1, 10, 
    131, 104, 2, 100, 0, 14, 101, 108, 105, 120, 105, 114, 95, 100, 111, 99, 115, 
    95, 118, 49, 108, 0, 0, 0, 4, 104, 2, ...>>, {:create_room, 3}} 


iex(19)> Room.empty_map(3,4) |> Room.create_room({1,2}, {3,3}) 
%{{1, 1} => " ", {1, 2} => "#", {1, 3} => "#", {1, 4} => "#", {1, 5} => "#", 
    {2, 1} => " ", {2, 2} => "#", {2, 3} => ".", {2, 4} => ".", {2, 5} => "#", 
    {3, 1} => " ", {3, 2} => "#", {3, 3} => ".", {3, 4} => ".", {3, 5} => "#", 
    {4, 2} => "#", {4, 3} => "#", {4, 4} => "#", {4, 5} => "#"} 
iex(20)>