lists:flatten无法正常工作的原因是Erlang中的字符串只是小整数列表。我们可以使用一个函数来处理这个问题,如果列表只是一个字符串,它就停止递归到嵌套列表中。
对于任意嵌套的字符串列表,您可以使用以下函数:
slab([]) ->
[];
slab([F|R]) ->
case io_lib:char_list(F) of
true -> [F|slab(R)];
false -> slab(F) ++ slab(R)
end.
它使用io_lib:char_list()来判断嵌套递归是否足够深。
操作示例:
1> slab([[["foo", "bar"], "baz", [[[["foobar"]]]], "froboz", "the end"]]).
["foo","bar","baz","foobar","froboz","the end"]
2>
一个小改进,可以使混合嵌套列表的使用成为可能:
slab([]) ->
[];
slab([F|R]) when is_list(F) ->
case io_lib:char_list(F) of
true -> [F|slab(R)];
false -> slab(F) ++ slab(R)
end;
slab([F|R]) ->
[F|slab(R)].
这个函数的行为与lists:flatten完全相同,只是它将字符串处理为非列表:
1> slab([[["foo", "bar"], "baz", [[[["foobar", atom]],[a,b,c]]], 2, "froboz", "the end"]]).
["foo","bar","baz","foobar",atom,a,b,c,2,"froboz","the end"]
list:foldl(fun erlang:'++'/2, [], List)
这个更短。 - nox