级联枚举。reduce/3 和地图。update/4
Cascade Enum.reduce/3 and Map.update/4
在我为 寻找一个好的解决方案的过程中,我尝试解决这个问题:
# This is the data I have.
#
trains = [:red_train, :blue_train]
train_stations = ["Station 1", "Station 2"]
# This stepping stone is calculated by a function.
#
stations_permutations = [
["Station 1", "Station 2"],
["Station 2", "Station 1"]
]
# This should be the result.
#
possible_routes =
[
%{
end: %{blue_train: "Station 2", red_train: "Station 1"},
start: %{blue_train: "Station 2", red_train: "Station 1"}
},
%{
end: %{blue_train: "Station 1", red_train: "Station 2"},
start: %{blue_train: "Station 1", red_train: "Station 2"}
},
%{
end: %{blue_train: "Station 1", red_train: "Station 2"},
start: %{blue_train: "Station 2", red_train: "Station 1"}
},
%{
end: %{blue_train: "Station 2", red_train: "Station 1"},
start: %{blue_train: "Station 1", red_train: "Station 2"}
}
]
我的问题:我想写一个函数list_routes/2
,它有trains
和train_stations
作为参数。它应该 return 带有地图列表(一张 start
和一张 end
),代表给定模型铁路上所有可能的路线。我在精神上陷入了 OO Ruby 领域,无法弄清楚如何以实用的方式解决这个问题。
我想 运行 遍历所有 station_permutations
并将它们匹配到 trains
。一次用于 start
一次用于 end
.
在Ruby中我会用一个循环来做。在 Elixir 中这是行不通的。我想 Enum.reduce
和 Map.update
是要走的路。但它是吗?我该如何级联这些?
def station_permutations(_train_stations) do
[
["Station 1", "Station 2"],
["Station 2", "Station 1"]
]
end
@doc """
Returns a list of all possible routes.
## Examples
iex> Trains.list_routes([:red_train, :blue_train], ["Station 1", "Station 2"])
[
%{
end: %{blue_train: "Station 2", red_train: "Station 1"},
start: %{blue_train: "Station 2", red_train: "Station 1"}
},
%{
end: %{blue_train: "Station 1", red_train: "Station 2"},
start: %{blue_train: "Station 1", red_train: "Station 2"}
},
%{
end: %{blue_train: "Station 1", red_train: "Station 2"},
start: %{blue_train: "Station 2", red_train: "Station 1"}
},
%{
end: %{blue_train: "Station 2", red_train: "Station 1"},
start: %{blue_train: "Station 1", red_train: "Station 2"}
}
]
"""
def list_routes(trains, train_stations) do
station_permutations(train_stations)
|> Enum.reduce(%{}, fn stations, acc ->
Map.update(acc, stations, nil, ???????)
end)
end
首先我会计算火车的所有可能状态:
possible_states = Enum.map(stations_permutations, &Enum.zip(trains, &1))
然后我会循环这些状态,在一个双循环中,一个用于起始状态,另一个用于结束状态:
for state_start <- possible_states, state_end <- possible_states do
%{start: state_start, end: state_end}
end
如果您真的想 reduce
用于学习目的,那么:
Enum.reduce(possible_states, [], fn state_start, acc ->
Enum.reduce(possible_states, acc, fn state_end, acc ->
[%{start: state_start, end: state_end} | acc]
end)
end)
注意外循环的初始累加器是 []
而内循环接收当前累加器 acc
。
在我为
# This is the data I have.
#
trains = [:red_train, :blue_train]
train_stations = ["Station 1", "Station 2"]
# This stepping stone is calculated by a function.
#
stations_permutations = [
["Station 1", "Station 2"],
["Station 2", "Station 1"]
]
# This should be the result.
#
possible_routes =
[
%{
end: %{blue_train: "Station 2", red_train: "Station 1"},
start: %{blue_train: "Station 2", red_train: "Station 1"}
},
%{
end: %{blue_train: "Station 1", red_train: "Station 2"},
start: %{blue_train: "Station 1", red_train: "Station 2"}
},
%{
end: %{blue_train: "Station 1", red_train: "Station 2"},
start: %{blue_train: "Station 2", red_train: "Station 1"}
},
%{
end: %{blue_train: "Station 2", red_train: "Station 1"},
start: %{blue_train: "Station 1", red_train: "Station 2"}
}
]
我的问题:我想写一个函数list_routes/2
,它有trains
和train_stations
作为参数。它应该 return 带有地图列表(一张 start
和一张 end
),代表给定模型铁路上所有可能的路线。我在精神上陷入了 OO Ruby 领域,无法弄清楚如何以实用的方式解决这个问题。
我想 运行 遍历所有 station_permutations
并将它们匹配到 trains
。一次用于 start
一次用于 end
.
在Ruby中我会用一个循环来做。在 Elixir 中这是行不通的。我想 Enum.reduce
和 Map.update
是要走的路。但它是吗?我该如何级联这些?
def station_permutations(_train_stations) do
[
["Station 1", "Station 2"],
["Station 2", "Station 1"]
]
end
@doc """
Returns a list of all possible routes.
## Examples
iex> Trains.list_routes([:red_train, :blue_train], ["Station 1", "Station 2"])
[
%{
end: %{blue_train: "Station 2", red_train: "Station 1"},
start: %{blue_train: "Station 2", red_train: "Station 1"}
},
%{
end: %{blue_train: "Station 1", red_train: "Station 2"},
start: %{blue_train: "Station 1", red_train: "Station 2"}
},
%{
end: %{blue_train: "Station 1", red_train: "Station 2"},
start: %{blue_train: "Station 2", red_train: "Station 1"}
},
%{
end: %{blue_train: "Station 2", red_train: "Station 1"},
start: %{blue_train: "Station 1", red_train: "Station 2"}
}
]
"""
def list_routes(trains, train_stations) do
station_permutations(train_stations)
|> Enum.reduce(%{}, fn stations, acc ->
Map.update(acc, stations, nil, ???????)
end)
end
首先我会计算火车的所有可能状态:
possible_states = Enum.map(stations_permutations, &Enum.zip(trains, &1))
然后我会循环这些状态,在一个双循环中,一个用于起始状态,另一个用于结束状态:
for state_start <- possible_states, state_end <- possible_states do
%{start: state_start, end: state_end}
end
如果您真的想 reduce
用于学习目的,那么:
Enum.reduce(possible_states, [], fn state_start, acc ->
Enum.reduce(possible_states, acc, fn state_end, acc ->
[%{start: state_start, end: state_end} | acc]
end)
end)
注意外循环的初始累加器是 []
而内循环接收当前累加器 acc
。