我想创建一个"玩家列表"。
该计划的用户可以说出他想要的玩家数量。
Amount = io:get_line("how many players? \n"),
Int = string:to_integer(Amount),
List = Lists:seq(1,Int).
但现在我想以[Player1,Player2 ... PlayerN]的形式创建一个玩家列表。
有人可以告诉我该怎么做吗?
答案 0 :(得分:2)
请记住,string:to_int/1
将返回元组,而不是单个值。另外请记住,用户在输入中做了一些非常疯狂的事情,所以你要检查一下。 (那就是说...当你只是想为自己编写一个程序来测试一个想法时,不管怎么样。)
{PlayerCount, _} = string:to_integer(io:get_line("How many players? ")),
非常简单。这有点麻烦。输入是它自己的世界,在玩具程序中多次思考这些东西是好的(并且给自己疯狂的输入以了解程序如何反应)。
从这里你可以做一些事情。如果你只想要一个元组列表,表明你有一个序列号为数字的玩家,那么列表理解就很容易了:
Players = [{player, Number} || Number <- lists:seq(1, PlayerCount)],
您也可以将其写为地图:
Players = lists:map(fun(N) -> {player, N} end, lists:seq(1, PlayerCount)),
我发现列表理解更具可读性。另一种方法是编写自己的自定义递归函数。您几乎从不需要这样做,但如果您是编程新手,那么这是一个很好的做法,并且在早期的过程中更具可读性,因为您可以准确地看到每次迭代发生的事情:
player_list(Count) -> player_list(1, Count, []).
player_list(Max, Max, Players) ->
lists:reverse(Players);
player_list(Current, Max, Players) ->
player_list(Current + 1, Max, [make_new_player(Current) | Players]).
请注意,上述内容相当于,但更自然地说明了:
player_list(Current, Max, Players) ->
Next = Current + 1,
case Next == Max of
true -> lists:reverse(Players);
false -> player_list(Next, Max, [make_new_player(Current) | Players])
end.
在一个程序的过程中,函数头中的匹配很多比一堆case
和if
语句更清晰可读。但是,如上所述,随着时间的推移,你最终会停止自己编写递归函数(大多数情况下)并发现自己使用 lot 列表操作(map,fold,filter,list comprehensions,等你获得经验。
make_new_player/0,1
的详细信息完全取决于您,当然 - 您没有说明您想要的数据结构类型,但您可以在那里做任何您想做的事情。以下是其他一些方法:
[make_new_player(Z) || Z <- lists:seq(1, PlayerCount)]
或
[#player{serial = Z} || Z <- lists:seq(1, PlayerCount)]