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函数,该函数将trainstrain_stations作为参数。它应该返回一个地图列表(一个start和一个end(,这些地图代表给定模型铁路上所有可能的路线。我在精神上被困在 OO Ruby 领域,无法弄清楚如何以功能性方式解决这个问题。

我想遍历所有station_permutations并将它们与trains相匹配。一次用于start,一次用于end.

在Ruby中,我会用循环来做到这一点。在长生不老药中,这是行不通的。我想Enum.reduceMap.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

最新更新