我有一个三重嵌套到case语句。在这个控制器动作中,这是一个完全可憎的事。
但是,我很高兴我在这种情况下,因为IMO最好的学习方法之一是看到代码在许多不同的方法中做同样的事情。这引出了我这个问题。
如何重构这段代码以使用case
语句而不是 case Nba.get_todays_games do
{:ok, games} ->
game_id = Map.get(games, "games")
|> Enum.random
|> Map.get("id")
:timer.sleep(1000)
case Nba.get_game_summary(game_id) do
{:ok, game} ->
team_id = Map.take(game, ["away", "home"])
|> Enum.random
|> elem(1)
|> Map.get("id")
:timer.sleep(1000)
case Nba.get_team_roster(team_id) do
{:ok, team} ->
player_id = Map.get(team, "players")
|> Enum.random
|> Map.get("id")
player_name = Map.get(team, "players")
|> Enum.find(fn %{"id" => id} -> player_id == id end)
|> Map.get("full_name")
end
end
end
?我在网上找到的所有例子都比这个例子更简单。
with {:ok, games} <- Nba.get_todays_games,
{:ok, game} <- Nba.get_todays_games(game_id),
{:ok, team} <- Nba.get_team_roster(team_id)
我注意到我不能像这样重构:
allprojects {
repositories {
google()
jcenter()}
}
task clean(type: Delete) {
delete rootProject.build``Dir}
buildscripts{
repositories {
// ...
maven {
url 'https://maven.fabric.io/public'
}
}
dependencies {
// ...
classpath 'io.fabric.tools:gradle:1.24.4'
}
}
我显然需要在两者之间做逻辑来获取game_id和team_id。谢谢你的帮助!
答案 0 :(得分:4)
只是将with
条款与您需要评估的内容一起散布,并且您已经准备好了:
with {:ok, games} <- Nba.get_todays_games,
game_id <- evaluate_game_id(),
{:ok, game} <- Nba.get_todays_games(game_id),
team_id <- evaluate_team_id(),
{:ok, team} <- Nba.get_team_roster(team_id)
我的建议是在单独的私有函数中提取评估以提高可读性。
答案 1 :(得分:4)
您可以在with {:ok, games} <- Nba.get_todays_games,
game_id = Map.get(games, "games")
|> Enum.random
|> Map.get("id"),
:timer.sleep(1000),
{:ok, game} <- Nba.get_game_summary(game_id),
...,
do: ...
之间添加作业或其他语句,只需确保用逗号分隔。
{{1}}